流畅的python中有很多奇技淫巧,整本书都在强调如何最大限度地利用Python 标准库。介绍了很多python的不常用的数据类型、操作、库等,对于入门python后想要提升对python的认识应该有帮助。目前读一遍记录了一些有共鸣的操作:
Python内置序列类型的主要分类:
按可存放的元素类型分为:容器序列和扁平序列
- 容器序列,就是什么都能作为元素往里放,包括另一个序列。需要注意的是,如果元素是序列类型,那么存放的往往是引用,需要小心。
常见的容器序列包括:list,tuple,array.array,collections.deque等。 - 扁平序列,存放的都是原子级元素,此时存放的是值而不会是引用。
常见的扁平序列包括:str,bytes,bytearray, memoryview, array.array等。
按序列能否被修改分为:可变序列与不可变序列
- 可变序列:可以进行增、删、改等操作的序列,包括list, bytearray, array.array, collections.deque, memoryview等。
- 不可变序列:不可进行上述操作的序列,包括tuple, str, bytes等。
字典的变种
标准库里collections模块中提供了很多与字典类型相似的变种。
OrderDict: 这个类型在添加键的时候,会保存顺序,因此键的迭代顺序总是一致的
ChainMap: 该类型可以容纳数个不同的映射对像,在进行键的查找时,这些对象会被当做一个整体逐个查找,直到键被找到为止
Counter: 这个映射类型会给键准备一个整数技术器,每次更行一个键的时候都会增加这个计数器,所以这个类型可以用来给散列表对象计数,或者当成多重集来用。
UserDict: 这个类其实就是把标准的dict用Python又写了一遍。一般用来给程序员想要通过继承dict创建自己的dict时,代替dict使用的。主要是因为直接继承原生dict会出现bug。
defaultdict:处理找不到的键的一个选择
当某个键不在映射里, 我们也希望也能得到一个默认值. 这就是 defaultdict , 它是 dict 的子类, 并实现了 missing 方法.
dict的实现以及导致的结果
键必须是可散列的: 一个可散列的对象必须满足以下要求。 (1) 支持 hash() 函数,并且通过 __hash__() 方法所得到的散列值是不变的。 (2) 支持通过 __eq__() 方法来检测相等性。 (3) 若 a == b 为真,则 hash(a) == hash(b) 也为真。 所有由用户自定义的对象默认都是可散列的,因为它们的散列值由 id() 来获取,而 且它们都是不相等的。 字典在内存上开销很大(用内存换效率)。 元组取代字典就能节省空间的原因有两个: (1) 避免了散列表所耗费的空间, (2) 无需把记录中字段的名字在每个元素里都存一遍。 键的查询很快 键的次序取决于添加顺序 往字典里添加新键可能会改变已有键的顺序set的实现以及导致的结果
结合的元素必须是可散列的 集合和消耗内存 可以很高效的判断元素是否存在于某个集合 元素的次序取决于被添加到集合里的顺序 往集合里添加元素,可能会改变集合里已有的元素次序collections.namedtuple 可以用来构建一个带字段名的元组和一个有名字的类
创建一个具名元组需要两个参数,一个是类名,另一个是类的各个字段的名字。后者
可以是由数个字符串组成的可迭代对象,或者是由空格分隔开的字段名组成的字符串。
>>> from collections import namedtuple >>> City = namedtuple('City', 'name country population coordinates') >>> tokyo = City('Tokyo', 'JP', 36.933, (35.689722, 139.691667)) >>> tokyo City(name='Tokyo', country='JP', population=36.933, coordinates=(35.689722, 139.691667)) >>> tokyo.population 36.933 >>> tokyo.coordinates (35.689722, 139.691667) >>> tokyo[1] 'JP' >>> City = namedtuple('City_Name', 'name country population coordinates') >>> tokyo = City('Tokyo', 'JP', 36.933, (35.689722, 139.691667)) >>> tokyo City_Name(name='Tokyo', country='JP', population=36.933, coordinates=(35.689722, 139.691667))当列表不是首选时
- 如果我们需要一个只包含数字的列表,那么 array.array 比 list 更高效。数组支持所
有跟可变序列有关的操作,包括 .pop、.insert 和 .extend。另外,数组还提供从文件
读取和存入文件的更快的方法,如 .frombytes 和 .tofile。 - set 专为检查元素是否存在做过优化
- memoryview 是一个内置类,它能让用户在不复制内容的情况下操作同一个数组的不同切
片。 - 使用NumPy和SciPy提供的高阶数组和矩阵操作
- 使用双向队列和其他形式的队列(collections.deque 双向队列类、queue类中的 Queue、LifoQueue和PriorityQueue、multiprocessing. Queue、heapq可以把可变序列当作堆队列或者优先队列来使用)
Python 格式化输出
在进行格式化输出时,%r 与 %s 的区别就好比 repr() 函数处理对象与 str() 函数处理对象的差别。
- %s -> str(),比较智能;
- %r -> repr(),处理较为简单和直接; 处理一些简单对象时,二者几乎没有差别.
本文重点列举一些二者的差异化用法:
