ccpocker ccpocker‘s blog

流畅的python读书笔记

2020-08-04
ccpocker

流畅的python

第2章:序列构成的数组

2.1 内置的序列类型

  • 容器序列:list,tuple,collections.deque
  • 扁平序列:str,bytes,btearray,array.array

2.2 列表推导和生成器表达式

symbols="$&#"
codes=[ord(symbol) for symbol in symbols]

列表推导的作用只有一个:$生成列表$

如果要生成列表以外的序列类型:生成器表达式

colors=["black","white"]
sizes=['S','M','L']

for tshirt in (f"{c} {s}" for c in colors for s in sizes):
    print(tshirt)

2.3 元组不仅仅是不可变的列表

元组其实是对数据的记录:元组中的每个元素都存放了记录中一个字段的数据,外加这个字段的位置。正是这个位置信息给数据赋予了意义。

元组拆包可以应用到任何可迭代对象上,唯一的硬性要求是,被可迭代对象中的元素数量必须要跟接受这些元素的元组的空档数一致。除非我们用*来表示忽略多余的元素。

在Python中,函数用*args来获取不确定数量的参数算是一种经典写法了。

>>> a,b*rest=range(5)
>>> a,b,rest
(0,1,[2,3,4])

具名元组:collection.namedtuple。它是一个工厂函数,可以用来构建一个带字段名的元组和一个有名字的类。

2.4 切片 切片的方式是调用seq._getitem__(slice(start,stop,step))

2.5 对序列使用”+”和”*”

>>> l=[1,2,3]
>>>print(l+[4],'\t',l*3)

记住对序列使用”+”和”*“都不会修改原有的对象,而是构建一个全新的序列。

建立由列表组成的列表,要防止引用到同一个列表。例如:

>>> a=[[_]*3]*3
>>> a[1,0]=1
>>> a
[[1, [], []], [1, [], []], [1, [], []]]

2.6 序列的增量赋值 “+=”

“*=”

2.7 list.sort()方法和内置函数sorted() sorted(iterable, cmp=None, key=None, reverse=False) 两种方法的区别:list.sort()直接对序列进行操作,返回None;sorted方法会新建一个列表进行返回。

2.8 用bisect来管理已经排序的数组

2.9 当列表不是首先时

  1. 数组: 如果我们只需要一个只包含数字的列表,array.array更高效,另外一个快速序列化数字类型的模块是pickle模块。
  2. 双向队列和其他形式的队列: collection.deque是一个线程安全,可以快速从两端添加或删除元素的数据类型。queue有Queue、lifoQueue、PrioritityQueue和JoinableQueue。

3 总结 Python序列类型最常见的分类就是可变和不可变序列。但另外一种分类方式也很有用,那就是把它们分为扁平序列和容器序列。前者的体积更小、速度更快而且用起来更简单,但是它只能保存一些原子性的数据,比如数字、字符和字节。容器序列则比较灵活,但是当容器序列遇到可变对象时,用户就需要格外小心了,因为这种组合时常会搞出一些“意外”,特别是带嵌套的数据结构出现时,用户要多费一些心思来保证代码的正确。 列表推导和生成器表达式则提供了灵活构建和初始化序列的方式,这两个工具都异常强大。如果你还不能熟练地使用它们,可以专门花时间练习一下。它们其实不难,而且用起来让人上瘾。元组在Python里扮演了两个角色,它既可以用作无名称的字段的记录,又可以看作不可变的列表。当元组被当作记录来用的时候,拆包是最安全可靠地从元组里提取不同字段信息的方式。新引入的*句法让元组拆包的便利性更上一层楼,让用户可以选择性忽略不需要的字段。具名元组也已经不是一个新概念了,但它似乎没有受到应有的重视。就像普通元组一样,具名元组的实例也很节省空间,但它同时提供了方便地通过名字来获取元组各个字段信息的方式,另外还有个实用的._asdict( )方法来把记录变成OrderedDict类型。 Python里最受欢迎的一个语言特性就是序列切片,而且很多人其实还没完全了解它的强大之处。比如,用户自定义的序列类型也可以选择支持NumPy中的多维切片和省略(…)。另外,对切片赋值是一个修改可变序列的捷径。重复拼接seq * n在正确使用的前提下,能让我们方便地初始化含有不可变元素的多维列表。增量赋值+=和*=会区别对待可变和不可变序列。在遇到不可变序列时,这两个操作会在背后生成新的序列。但如果被赋值的对象是可变的,那么这个序列会就地修改——然而这也取决于序列本身对特殊方法的实现。序列的sort方法和内置的sorted函数虽然很灵活,但是用起来都不难。这两个方法都比较灵活,是因为它们都接受一个函数作为可选参数来指定排序算法如何比较大小,这个参数就是key参数。key还可以被用在min和max函数里。如果在插入新元素的同时还想保持有序序列的顺序,那么需要用到bisect.insortbisect.bisect的作用则是快速查找。 除了列表和元组,Python标准库里还有array.array。另外,虽然NumPy和SciPy都不是Python标准库的一部分,但稍微学习一下它们,会让你在处理大规模数值型数据时如有神助。本章末尾介绍了collections.deque这个类型,它具有灵活多用和线程安全的特性。表2-3将它和列表的API做了比较。本章最后也提及了一些标准库中的其他队列类型的实现。


上一篇 GAN

Comments

Content