list是一种按_顺序_排列的可变元素集合。
像大多数集合一样(参见内置的tuple、dict和set),数组可以持有任意(或多种)数据类型的引用,包括其他数组。
数组可以通过切片语法整体或部分复制,也可以使用<list>.copy()来复制。
与任何序列一样,lists中的元素可以从左边按0-based index编号引用,也可以从右边按-1-based index编号引用。
数组既支持通用序列操作,也支持可变序列操作,例如min(<list>)/max(<list>)、<list>.index()、<list>.append()和<list>.reverse()。
可以使用for item in <list>结构遍历list中的元素。
当同时需要元素的下标和值时,可以使用for index, item in enumerate(<list>)。
Python 还提供了许多处理数组的实用数组方法。
下面会介绍其中一部分list methods。
注意,当你用list-method操作一个list时,你改变的是传入的那个数组对象。
如果你不想修改原来的list,至少需要通过切片或<list>.copy()对它做一个shallow copy。
要把元素添加到已有数组的末尾,也就是“右侧”,可以使用<list>.append(<item>):
>>> numbers = [1, 2, 3]
>>> numbers.append(9)
>>> numbers
[1, 2, 3, 9]
与_追加_不同,<list>.insert()让你可以把元素添加到数组中的_指定下标_。
它接收 2 个形参:
<index>。<item>。注意:如果给定的index是 0,元素会被添加到list的开头(“左侧”)。
如果传入的index大于list上最后一个index,元素会被添加到最后一个位置,效果等同于使用<list>.append(<item>)。
>>> numbers = [1, 2, 3]
>>> numbers.insert(0, -2)
>>> numbers
[-2, 1, 2, 3]
>>> numbers.insert(1, 0)
>>> numbers
[-2, 0, 1, 2, 3]
可以用<list>.extend(<item>)把一个已有的数组与另一个可迭代对象(例如set、tuple、str或list)中的元素合并起来。
这个可迭代对象会被_解包_,其中的元素会按顺序追加(在这种情况下使用<list>.append(<item>)会把整个可迭代对象作为单个元素添加进去。)。
>>> numbers = [1, 2, 3]
>>> other_numbers = [5, 6, 7]
>>> numbers.extend(other_numbers)
>>> numbers
[1, 2, 3, 5, 6, 7]
>>> numbers.extend([8, 9])
>>> numbers
[1, 2, 3, 5, 6, 7, 8, 9]
>>> numbers.append([8,9])
>>> numbers
[1, 2, 3, 5, 6, 7, 8, 9, [8, 9]]
要从数组中删除元素,使用<list>.remove(<item>),把要删除的元素作为实参传入。
如果要删除的元素不在list中,<list>.remove(<item>)会抛出ValueError。
>>> numbers = [1, 2, 3]
>>> numbers.remove(2)
>>> numbers
[1, 3]
# Trying to remove a value that is not in the list throws a ValueError
>>> numbers.remove(0)
ValueError: list.remove(x): x not in list
另一种做法是使用<list>.pop(<index>)方法,它既能移除元素,也能把该元素return出来供使用。
<list>.pop(<index>)接受一个可选的形参:要移除并返回的元素的index。
如果没有指定(可选的)index实参,list的最后一个元素会被移除并返回。
如果指定的index大于最后一个元素的index,则会引发IndexError。
>>> numbers = [1, 2, 3]
>>> numbers.pop(0)
1
>>> numbers
[2, 3]
>>> numbers.pop()
3
>>> numbers
[2]
>>> numbers.pop(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: pop index out of range
可以用list.clear()移除list中的所有元素。它不接收任何形参。
>>> numbers = [1, 2, 3]
>>> numbers.clear()
>>> numbers
[]
<list>.reverse()方法会就地反转元素的顺序。
>>> numbers = [1, 2, 3]
>>> numbers.reverse()
>>> numbers
[3, 2, 1]
借助<list>.sort(),数组可以_就地重新排序。
默认的排序顺序是从左起的_升序。
Python 文档提供了更多排序技巧和方法。
>>> names = ["Tony", "Natasha", "Thor", "Bruce"]
# The default sort order is *ascending*.
>>> names.sort()
>>> names
["Bruce", "Natasha", "Thor", "Tony"]
如果需要_降序_,就传入reverse=True实参:
>>> names = ["Tony", "Natasha", "Thor", "Bruce"]
>>> names.sort(reverse=True)
>>> names
["Tony", "Thor", "Natasha", "Bruce"]
如果不想修改原数组,可以使用内置的sorted(<iterable>)函数返回一个排好序的副本。
>>> names = ["Tony", "Natasha", "Thor", "Bruce"]
>>> sorted(names)
['Bruce', 'Natasha', 'Thor', 'Tony']
可以用list.count(<item>)计算某个元素在数组中出现的次数。
它把要统计的item作为实参,并返回该元素在list中出现的总次数。
>>> items = [1, 4, 7, 8, 2, 9, 2, 1, 1, 0, 4, 3]
>>> items.count(1)
3
<list>.index(<item>)会返回传入元素_第一次出现_的index编号。
如果没有出现,则会引发ValueError。
如果不需要元素的确切位置,用内置的in运算符检查数组是否包含某个给定的值会更高效。
下标从左边开始,以 0 为基准,所以“第一个”元素的位置是0。
下标也可以从右边开始,从-1起算。
>>> items = [7, 4, 1, 0, 2, 5]
>>> items.index(4)
1
>>> items.index(10)
ValueError: 10 is not in list
还可以提供start和end下标,把搜索范围缩小到list的某个特定区段:
>>> names = ["Tina", "Leo", "Thomas", "Tina", "Emily", "Justin"]
>>> names.index("Tina")
0
>>> names.index("Tina", 2, 5)
3
Chaitana 拥有一个非常受欢迎的主题公园。在风景优美的园区正中央,她只有一个游乐项目:世界最大的过山车(TM)。尽管只有这一个游乐设施,人们还是从世界各地赶来,排上几个小时的队,只为了能坐上 Chaitana 的超级过山车。
这个项目有两个队列,每个都用一个list来表示:
有人请你写一些代码,来更好地管理公园里的游客。你需要在游客(还有你的老板 Chaitana!)发飙之前,尽快把下面这些函数实现出来。请务必仔细阅读。有些任务要求你修改或更新已有的队列,有些则要求你复制一份。
定义add_me_to_the_queue()函数,它接受 4 个形参<express_queue>, <normal_queue>, <ticket_type>, <person_name>,返回相应的队列,其中已经加上了这个人的名字。
<ticket_type>是一个int:1 表示 express_queue,0 表示 normal_queue。<person_name>是要加入相应队列的那个人的名字(类型为str)。>>> add_me_to_the_queue(express_queue=["Tony", "Bruce"], normal_queue=["RobotGuy", "WW"], ticket_type=1, person_name="RichieRich")
...
["Tony", "Bruce", "RichieRich"]
>>> add_me_to_the_queue(express_queue=["Tony", "Bruce"], normal_queue=["RobotGuy", "WW"], ticket_type=0, person_name="HawkEye")
....
["RobotGuy", "WW", "HawkEye"]
有个人很晚才到公园,却想排到朋友们正等着的那个队列里。可是他不知道朋友们站在哪儿,而且手机也没信号,没法打电话问。
定义find_my_friend()函数,它接受 2 个形参queue和friend_name,返回这个名字在队列中的位置。
<queue>是排队的人组成的list。<friend_name>是你要查找下标的那个朋友的名字(也就是他在队列中的位置)。记住:下标从左边数从 0 开始,从右边数从 -1 开始。
>>> find_my_friend(queue=["Natasha", "Steve", "T'challa", "Wanda", "Rocket"], friend_name="Steve")
...
1
既然已经找到了朋友们(在上面的任务 2 里),这位迟到的人就想插到朋友们排队的位置上。定义add_me_with_my_friends()函数,它接受 3 个形参queue、index和person_name。
<queue>是排队的人组成的list。<index>是新成员要加入的位置。<person_name>是要加在下标位置上的那个人的名字。返回更新后的队列,其中已经加上了这位迟到者的名字。
>>> add_me_with_my_friends(queue=["Natasha", "Steve", "T'challa", "Wanda", "Rocket"], index=1, person_name="Bucky")
...
["Natasha", "Bucky", "Steve", "T'challa", "Wanda", "Rocket"]
你刚从队列那边听说,有个特别讨厌的人又推人、又大喊大叫,还在捣乱。你得把这个坏家伙赶出去,谁让他行为这么差!
定义remove_the_mean_person()函数,它接受 2 个形参queue和person_name。
<queue>是排队的人组成的list。<person_name>是需要被赶出去的那个人的名字。返回更新后的队列,其中已经去掉了这个讨厌鬼的名字。
>>> remove_the_mean_person(queue=["Natasha", "Steve", "Eltran", "Wanda", "Rocket"], person_name="Eltran")
...
["Natasha", "Steve", "Wanda", "Rocket"]
你可能没见过两个毫无血缘关系却长得一模一样的人,但你_肯定_见过毫无血缘关系、名字却完全相同的人(也就是同名的人)!今天到场的人里,这种人看起来还挺多。你想知道某个名字在队列里出现了多少次。
定义how_many_namefellows()函数,它接受 2 个形参queue和person_name。
<queue>是排队的人组成的list。<person_name>是你认为可能在队列里出现不止一次的名字。返回person_name出现的次数,类型为int。
>>> how_many_namefellows(queue=["Natasha", "Steve", "Eltran", "Natasha", "Rocket"], person_name="Natasha")
...
2
可惜今天公园里人太多了,你需要把普通队列里的最后一个人移出去(你会给他一张代金券,让他改天再来走快速通道)。你得定义remove_the_last_person()函数,它接受 1 个形参queue,也就是排队的人组成的数组。
你应该更新这个list,同时也要return被移出去的那个人的名字,这样才能给他开一张代金券。
>>> remove_the_last_person(queue=["Natasha", "Steve", "Eltran", "Natasha", "Rocket"])
...
'Rocket'
出于管理上的需要,你需要把某个队列里的所有名字按字母顺序排好。
定义sorted_names()函数,它接受 1 个实参queue(排队的人组成的list),并返回这个list经过sorted排序后的副本。
>>> sorted_names(queue=["Natasha", "Steve", "Eltran", "Natasha", "Rocket"])
...
['Eltran', 'Natasha', 'Natasha', 'Rocket', 'Steve']