1.8. 列表 101

列表是Python中使用最频繁的数据类型。如果你对列表仅有的经验是在VB中的数组或Java中的 Lists ,那么振作起来,面对Python列表吧。

Note
Python的列表如同Perl中的数组。在Perl中,用来保存数组的变量总是以 @ 字符开始;在Python中,变量可以起任何名字,并且Python在内部记录它的数据类型。
Note
Python的列表比Java中的数据要丰富的多(尽管它可能是生命之外你最想要使用的东西之一)。一个更好的类比应该是 Vector 类,它可以保存任意的对象并且当增加一个元素时可以动态扩展。

例 1.14. 定义列表

>>> li = ["a", "b", "mpilgrim", "z", "example"] 1
>>> li
['a', 'b', 'mpilgrim', 'z', 'example']
>>> li[0]                                       2
'a'
>>> li[4]                                       3
'example
1

首先我们定义了一个有5个元素的列表。注意它们保持着初始的顺序。这不是偶然。列表是一个用方括号包括起来的有序元素集。

2 列表可以用作以0下标开始的数组。任何一个非空列表的第一个元素总是 li[0]
3 这个5元素列表的最后一个元素是 li[4],因为列表总是从0开始。

例 1.15. 负的列表索引

>>> li
['a', 'b', 'mpilgrim', 'z', 'example']
>>> li[-1] 1
'example'
>>> li[-3] 2
'mpilgrim'
1 负数索引从列表的尾部开始返向计数存取元素。任何一个非空的列表最后一个元素总是 li[-1]
2 如果负数索引使你感到糊涂,可以这样理解:li[n] == li[n - len(li)]。所以在这个列表里,li[2] == li[2 - 5] == li[-3].

例 1.16. 分片一个列表

>>> li
['a', 'b', 'mpilgrim', 'z', 'example']
>>> li[1:3]  1
['b', 'mpilgrim']
>>> li[1:-1] 2
['b', 'mpilgrim', 'z']
>>> li[0:3]  3
['a', 'b', 'mpilgrim'
1

你可以通过指定2个索引得到列表的子集,叫做一个“分片”。返回值是一个新的列表,它包含了列表中按顺序从第一个分片索引(这里为 li[1])开始,直到但是不包括第二个分片索引(这里为 li[3])的所有元素。

2

如果一个或两个分片索引是负数,分片也可以工作。如果对你有帮助,你可以这样理解:从左向右阅读列表,第一个分片索引指定了你想要的第一个元素,第二个分片索引指定了第一个你不想要的元素。返回的值为在其间的每个元素。

3 列表从0开始,所以 li[0:3] 返回列表的前3个元素,开始从 li[0],直到但不包括 li[3]

例 1.17. 分片缩写

>>> li
['a', 'b', 'mpilgrim', 'z', 'example']
>>> li[:3] 1
['a', 'b', 'mpilgrim']
>>> li[3:] 2
['z', 'example']
>>> li[:]  3
['a', 'b', 'mpilgrim', 'z', 'example']
1 如果任一个分片索引为0,你可以将其省略,默认为0。所以 li[:3] 同前一个例子的 li[0:3] 一样。
2 注意这里的对称写法。在这个5元素列表中,li[:3] 返回前三个元素,而 li[3:] 返回后两个元素。实际上,li[:n] 将总是返回前 n 个元素,而 li[n:] 将返回其它的元素。
3 如果两个分片索引均省略,将包括列表的所有元素。但是与原始的列表 li 不是同一个,它是一个新的列表,恰好拥有与 li 全部一样的元素。li[:] 是生成一个列表拷贝的缩写。

例 1.18. 向列表中增加元素

>>> li
['a', 'b', 'mpilgrim', 'z', 'example']
>>> li.append("new")               1
>>> li
['a', 'b', 'mpilgrim', 'z', 'example', 'new']
>>> li.insert(2, "new")            2
>>> li
['a', 'b', 'new', 'mpilgrim', 'z', 'example', 'new']
>>> li.extend(["two", "elements"]) 3
>>> li
['a', 'b', 'new', 'mpilgrim', 'z', 'example', 'new', 'two', 'elements']
1 append 增加单个元素到列表的尾部。
2 insert 向列表中插入单个元素。数值参数是使得列表增加的第一个元素的索引。注意列表元素不需要唯一,现在有两个独立的元素拥有 new 这个值,li[2]li[6]
3 extend 连接列表。注意不要用多个参数调用 extend ,要使用一个列表参数调用。在这种情况下,列表有两个元素。

例 1.19. 搜索列表

>>> li
['a', 'b', 'new', 'mpilgrim', 'z', 'example', 'new', 'two', 'elements']
>>> li.index("example") 1
5
>>> li.index("new")     2
2
>>> li.index("c")       3
Traceback (innermost last):
  File "<interactive input>", line 1, in ?
ValueError: list.index(x): x not in list
>>> "c" in li           4
0
1 index 在列表中查找值第一次的出现并返回索引值。
2 index 在列表中查找值 第一次 的出现。在本例中, new 在列表中出现了两次,在 li[2]li[6],但是 index 将只返回第一个索引,2
3

如果在列表中没有找到值,Python会引发一个异常。这一点与大部分的语言相当不同,大部分语言将会返回某个无效索引。尽管这种处理可能看上去令人讨厌,它仍然是好东西,因为它说明你的程序会由于源代码的问题而崩溃,好于在后面当你使用无效索引而引起崩溃。

4 要测试一个值是否在列表内,使用 in,如果值找到了,它返回 1 ,或者没找到则为 0
Note
在Python中不存在布尔类型。在一个布尔上下文中(象 if 语句),0 是假,所有其它的数值为真。这一点也可以扩展到其它类型。一个空串(""),一个空列表([]),和一个空字典({})都是假,所有其它的字符串,列表,和字典是真。

例 1.20. 从列表中除去元素

>>> li
['a', 'b', 'new', 'mpilgrim', 'z', 'example', 'new', 'two', 'elements']
>>> li.remove("z")   1
>>> li
['a', 'b', 'new', 'mpilgrim', 'example', 'new', 'two', 'elements']
>>> li.remove("new") 2
>>> li
['a', 'b', 'mpilgrim', 'example', 'new', 'two', 'elements']
>>> li.remove("c")   3
Traceback (innermost last):
  File "<interactive input>", line 1, in ?
ValueError: list.remove(x): x not in list
>>> li.pop()         4
'elements'
>>> li
['a', 'b', 'mpilgrim', 'example', 'new', 'two']
1 remove 从列表中除掉第一次出现的值。
2

remove 除掉第一次出现的值。在本例中,new 在列表中出现了两次,但是 li.remove("new") 仅除掉了第一次出现的值。

3 如果在列表中没有找到值,Python引发一个异常。它反映了 index 方法的行为。
4 pop 是一个有趣的东西。它执行两件事:除掉列表的最后一个元素,然后返回除掉的值。注意这一点同 li[-1]不同,后者返回一个值但不改变列表,也不同于 li.remove(value),后者改变列表但不返回值。

例 1.21. 列表操作符

>>> li = ['a', 'b', 'mpilgrim']
>>> li = li + ['example', 'new'] 1
>>> li
['a', 'b', 'mpilgrim', 'example', 'new']
>>> li += ['two']                2
>>> li
['a', 'b', 'mpilgrim', 'example', 'new', 'two']
>>> li = [1, 2] * 3              3
>>> li
[1, 2, 1, 2, 1, 2]
1 列表也可以用 + 操作符连接起来。list = list + otherlist 相当于 list.extend(otherlist)。但是 + 操作符将连接后的列表作为一个值返回,而 extend 仅修改存在的列表。这就是说对于大列表来说, extend 的执行速度要快一些。
2 Python支持 += 操作符。li += ['two'] 相当于 li = li + ['two']+= 操作符可用于列表,字符串,和整数,并且它也可以在用户定义类中被重载。(第三章会有更多关于类的内容)
3

* 操作符作为一个重复符可用在列表上。li = [1, 2] * 3 相当于 li = [1, 2] + [1, 2] + [1, 2], 将三个列表连成一个。


进一步阅读