3.1. 数据结构

Python 包含了一些标准的编程数据结构,例如: listtupledict, 和 set,来作为内置类型的一部分。大多数应用程序都不会用到其他的数据结构,但如果遇到了,标准库就会为这些将要用到的结构提供一个强大的、经过良好测试的版本。

enum 模块提供了一个 枚举类型 的实现,并且拥有可迭代性和可比较性。 它可以用来代替字面量字符串或者整数给值创建更具定义性的标识符。

collections 模块包含了对一些在其他模块中出现的数据结构的扩展实现。例如:Deque 是一个双端队列,允许从队列的两端进行增加或者删除元素。defaultdict 是一个字典,能在键不存在的情况下返回一个默认值,而 OrderedDict 能保存元素添加的顺序。namedtuple 继承自普通的 tuple ,除了数字索引外,它还给了每个元素一个属性名。

对于大量数据,使用 array 可能会比使用 list 有更高效的内存利用率。由于 array 限制了单数据类型,所以它能使用比通用的 list 更紧凑的内存表示。同时, array 实例能够使用许多与 list 相同的方法来操纵,因此,在一个没有太多变化的应用中使用 array 来代替 list 是可行的。

在一个序列化的结构中对元素进行排序是数据操作的一个基本方面。Python 的 list 包含了一个 sort() 方法,但有时候,维护一个已经排好序的列表而不必在每次内容发生改变都去重排一次要高效得多。heapq 模块的函数能在修改列表内容的同时,使用较低的开销来保持列表的排列顺序。

构建有序列表或者数组的另一个切入点是 bisect 模块。它使用二分查找法来确定新元素的插入位置,并且它也是对频繁更改的列表进行重排的另一个选择。

尽管内置的 list 能够使用 insert() 和 pop() 方法来模拟队列,但它不是线程安全的。线程间的真正排序通讯使用的是 queue 模块。 multiprocessing 包含了一个在进程间运行的 Queue 版本,使得将一个多线程程序转换为一个多进程的程序更加简单。

struct 对于解码另一个程序的数据非常有用, 也许它会将一个来自二进制文件或者数据流的数据转换为 Python 的原生类型,来使得操作更加方便。

本章包含两个与内存管理相关的模块。对于高度相关联的数据结构,比如:图和树,使用 weakref 来保持引用,同时,允许垃圾收集器在不再需要对象的时候清空它们。 使用 copy 模块的函数来复制数据结构以及它们的内容,包括使用 deepcopy() 函数来做递归地复制。

调试数据结构是非常耗时的,尤其是涉及到打印输出大型队列或者字典的时候。 使用 pprint 模块创建可打印到控制台或者可以写入到日志文件中的更易读的表现形式来简化调试。

最后,如果这些可用的类型仍然不满足需求,那么从某个原生类型中派生出一个子类来自定义一下,或者使用一个在 collections 中定义的抽象基类来创建一个新的容器类型。