列表
列表(list),是一种结构化的、非标量类型,它的值是有序序列,每个值都可以通过索引进行标识。
列表定义
- 列表用 [ ] 表示,是有序集合,索引从0开始,最后一个索引可用 -1 表示
- 列表是一种序列类型,创建后可以随意被修改
- 使用方括号 [ ] 或 list() 创建,元素间用逗号 , 分隔
- 列表中各元素类型可以不同,无长度限制
- 方括号 [ ] 真正创建一个列表,赋值仅传递引用
列表类型操作函数和方法
| 方法名称 | 功能 |
|---|---|
| s[i] = x | 替换列表s第i元素为x |
| ls[i: j: k] = lt | 用列表lt替换ls切片后所对应元素子列表 |
| ls += lt | 更新列表ls,将列表lt元素增加到列表ls中 |
| *ls = n | 更新列表ls,其元素重复n次 |
| ls.clear() | 删除列表ls中所有元素 |
| ls.copy() | 生成一个新列表,赋值ls中所有元素 |
| ls.insert(i,x) | 在列表ls的第i位置增加元素x |
| ls.pop(i) | 将列表ls中第i位置元素取出并删除该元素,默认返回最后元素 |
| ls.remove(x) | 将列表ls中出现的第一个元素x删除 |
| ls.reverse() | 将列表ls中的元素反转 |
| ls.extend() | 将多个值附加到列表末尾;拼接不修改原来序列的值,但是extend修改;a[len(a) : ] = b效果同extend; |
| append() | 在末尾直接添加 |
| del() | 如果知道索引,可用del |
| sort() | 永久对原列表排序,不返回排序后列表的副本; sort(reverse = True) 反序 |
| sorted() | 临时排序,返回排序后列表的副本、reverse():永久反转列表元素,不返回任何值 |
| sort(key,reverse) | 将其设置为一个用于排序的函数; reverse(True、False) 是否按相反顺序对列表排序 |
遍历整个列表
for 变量名 in 列表名:
每个缩进代码行都是循环一部分
复制列表
同时省略起始和终止索引,eg、 player[:] ;如果只是将变量复制,两个变量将同时指向同一个列表;或者调用方法 copy(); 或者 list(列表名)
列表切片
- 支持正向索引(0)和负向索引(-1);
- 默认步长为1;
1 | |
1 | |
1 | |
1 | |
列表生成式
列表推导
列表推导可以帮助我们把一个序列或是其他可迭代类型中的元素过滤或是加工,然后再新建一个列表。Python 内置的 filter 和 map 函数组合起来也能达到这一效果,但是可读性上打了不小的折扣。
1
2
3
4
5
6
7
8
9
10
11>>> colors = ['black', 'white']
>>> sizes = ['S', 'M', 'L']
>>> tshirts = [(color, size) for color in colors for size in sizes]
>>> tshirts
[('black', 'S'), ('black', 'M'), ('black', 'L'), ('white', 'S'),
('white', 'M'), ('white', 'L')]生成器表达式
虽然也可以用列表推导来初始化元组、数组或其他序列类型,但是生成器表达式是更好的选择。这是因为生成器表达式背后遵守了迭代器协议,可以逐个地产出元素,而不是先建立一个完整的列表,然后再把这个列表传递到某个构造函数里。前面那种方式显然能够节省内存。
生成器表达式的语法跟列表推导差不多,只不过把方括号换成圆括号而已。
1
2
3
4
5>>> symbols = '$¢£¥€¤'
>>> tuple(ord(symbol) for symbol in symbols)
(36, 162, 163, 165, 8364, 164)如果要生成[1x1, 2x2, 3x3, …, 10x10]怎么做?方法一是循环:
1
2
3
4
5
6>>> L = []
>>> for x in range(1, 11):
... L.append(x * x)
...
>>> L
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]但是循环太繁琐,而列表生成式则可以用一行语句代替循环生成上面的list:
1
2>>> [x * x for x in range(1, 11)]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]写列表生成式时,把要生成的元素x * x放到前面,后面跟for循环,就可以把list创建出来
for循环后面还可以加上if判断,这样我们就可以筛选出仅偶数的平方:
1
2[x * x for x in range(1, 11) if x % 2 == 0]
[4, 16, 36, 64, 100]还可以使用两层循环,可以生成全排列:
1
2[m + n for m in 'ABC' for n in 'XYZ']
['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']列表生成式也可以使用两个变量来生成list:
1
2
3
4>>> d = {'x': 'A', 'y': 'B', 'z': 'C' }
>>> [k + '=' + v for k, v in d.items()]
['y=B', 'x=A', 'z=C']if … else
以下代码正常输出偶数:
1
2>>> [x for x in range(1, 11) if x % 2 == 0]
[2, 4, 6, 8, 10]但是,我们不能在最后的if加上else:
1
2
3
4
5>>> [x for x in range(1, 11) if x % 2 == 0 else 0]
File "<stdin>", line 1
[x for x in range(1, 11) if x % 2 == 0 else 0]
SyntaxError: invalid syntax这是因为跟在for后面的if是一个筛选条件,不能带else,否则如何筛选?
另一些童鞋发现把if写在for前面必须加else,否则报错:
1
2
3
4
5
6>>> [x if x % 2 == 0 for x in range(1, 11)]
File "<stdin>", line 1
[x if x % 2 == 0 for x in range(1, 11)]
^
SyntaxError: invalid syntax这是因为for前面的部分是一个表达式,它必须根据x计算出一个结果。因此,考察表达式:x if x % 2 == 0,它无法根据x计算出结果,因为缺少else,必须加上else:
1
2>>> [x if x % 2 == 0 else -x for x in range(1, 11)]
[-1, 2, -3, 4, -5, 6, -7, 8, -9, 10]上述for前面的表达式x if x % 2 == 0 else -x才能根据x计算出确定的结果。可见,在一个列表生成式中,for前面的if … else是表达式,而for后面的if是过滤条件,不能带else。连接列表代价更高,因为创建了一个新列表,并复制了对象。
下面的代码演示了如何定义列表、如何遍历列表以及列表的下标运算。
1 | |
下面的代码演示了如何向列表中添加元素以及如何从列表中移除元素。
1 | |
和字符串一样,列表也可以做切片操作,通过切片操作我们可以实现对列表的复制或者将列表中的一部分取出来创建出新的列表,代码如下所示。
1 | |
下面的代码实现了对列表的排序操作。
1 | |
我们还可以使用列表的生成式语法来创建列表,代码如下所示。
1 | |






