《Fluent Python》2:Sequences
[TOC]
总览
Python内置的sequences类型包括两类
- Container sequences
- 可以包含不同类型的数据,包括list,tuple,collections.deque
- Flat sequences
- 只能包含同一类数据,比如str,bytes,bytearray,memoryview,array.array等
另一种分法是利用可变、不可变分,比如tuple,str是不可变(注意,a='abc', a[1]='d'
是非法的)。
继承关系总览
列表生成器和生成器表达式
列表生成器(List Comprehensions)
已经比较熟悉,在此不赘述,注意以下几点
- Python2中,列表生成器可能会Leak Variables,将生成器表达式里的变量外泄到生成器外层的作用域,但从Python3开始不会这样了。
- 多维列表生成器,用于代替双重for循环,第一章的例子也有用到。
|
|
- 不会占内存,所以如果直接用在for循环里,类似yield,可以节省内存
生成器表达式
不一定用来生成列表,还可以用来生成元组等
|
|
Tuples
有两种使用元组(tuple)的方式,一种是immutable lists
,一种是匿名记录(records with no field names)
Immutable Lists
作为不可变列表使用的时候,你(或许才)会发现tuple和list很像,比如常用的一些方法,只要不是涉及到元素的增删的,list有的tuple都有,下面列出部分
匿名记录
通俗地说就是C的结构体,不过不需要指定field的名字。
Tuple Unpacking
当作为匿名记录使用时,元组可以看做是变量的打包,而解包就是从元组中取出这些变量的方式。
除了隐式解包,还有一个特殊的*
语法可以把元组解包
|
|
嵌套元组解包,只需要加对应的括号
带名元组
其实在第一章也用到过,就是Card = collections.namedtuple('Card', ['rank', 'suit'])
,这就和C的结构体一样了。
切片
|
|
基本原理不再赘述,注意切片是view不是副本
另外,当使用切片赋值,右侧变量必须是可迭代的。切片长度和右侧变量长度不等时,原列表会缩短,而并不会像numpy一样广播!
加号和乘号
加号是拼接,乘号是倍增
注意一个陷阱,例2-12的做法是正确的,用列表推导生成嵌套列表;而2-13看起来正确的做法是错误的,因为这样生成的外层列表,其三个元素并不是独立的三个列表,而是三个对同一列表的引用,其实是重复的。
其实把它们翻译成for循环会看得更清楚,是因为row的位置不一样。
有一个可视化在线调试器,https://pythontutor.com/