目录

《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'是非法的)。

继承关系总览

/images/image-20220518000842164.png

列表生成器和生成器表达式

列表生成器(List Comprehensions)

已经比较熟悉,在此不赘述,注意以下几点

  • Python2中,列表生成器可能会Leak Variables,将生成器表达式里的变量外泄到生成器外层的作用域,但从Python3开始不会这样了。
  • 多维列表生成器,用于代替双重for循环,第一章的例子也有用到。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
import collections

Card = collections.namedtuple('Card', ['rank', 'suit'])

class FrenchDeck:
    ranks = [str(n) for n in range(2, 11)] + list('JQKA')
    suits = 'spades diamonds clubs hearts'.split()

    def __init__(self):
        self._cards = [Card(rank, suit) for suit in self.suits
                                        for rank in self.ranks]
  • 不会占内存,所以如果直接用在for循环里,类似yield,可以节省内存

生成器表达式

不一定用来生成列表,还可以用来生成元组等

1
2
>>> symbols= 'abcde'
>>> tuple(ord(symbol) for symbol in symbols)

Tuples

有两种使用元组(tuple)的方式,一种是immutable lists,一种是匿名记录(records with no field names)

Immutable Lists

作为不可变列表使用的时候,你(或许才)会发现tuple和list很像,比如常用的一些方法,只要不是涉及到元素的增删的,list有的tuple都有,下面列出部分

/images/image-20220518104705367.png

匿名记录

通俗地说就是C的结构体,不过不需要指定field的名字。

/images/image-20220518001955051.png

Tuple Unpacking

当作为匿名记录使用时,元组可以看做是变量的打包,而解包就是从元组中取出这些变量的方式。

除了隐式解包,还有一个特殊的*语法可以把元组解包

1
2
3
4
5
6
7
8
>>> divmod(20, 8)
(2, 4)
>>> t = (20, 8)
>>> divmod(*t)
(2, 4)
>>> quotient, remainder = divmod(*t)
>>> quotient, remainder
(2, 4)

嵌套元组解包,只需要加对应的括号

/images/image-20220518103410912.png

带名元组

其实在第一章也用到过,就是Card = collections.namedtuple('Card', ['rank', 'suit']),这就和C的结构体一样了。

切片

1
s[start🔚step]

基本原理不再赘述,注意切片是view不是副本

另外,当使用切片赋值,右侧变量必须是可迭代的。切片长度和右侧变量长度不等时,原列表会缩短,而并不会像numpy一样广播!

/images/image-20220518105104427.png

加号和乘号

加号是拼接,乘号是倍增

注意一个陷阱,例2-12的做法是正确的,用列表推导生成嵌套列表;而2-13看起来正确的做法是错误的,因为这样生成的外层列表,其三个元素并不是独立的三个列表,而是三个对同一列表的引用,其实是重复的。

/images/image-20220518105721679.png

其实把它们翻译成for循环会看得更清楚,是因为row的位置不一样。

/images/image-20220518110557229.png

有一个可视化在线调试器,https://pythontutor.com/