对于 Python 中内置的 list, tuple, set and dict 这样的简单数据结构,我们已经很熟悉了。
一般的应用场景,有这些简单的数据结构,也已经够用了。如果是比较复杂的场景,需要其他更高级的
数据结构,Python 也为我们提供了支持。本文先学习如下几种:
- collections
- array
- heapq
- bisect
- weakref
- copy
- pprint
- singly linked-list
Collections
在 collections 模块中,包含了一些非常有用的数据结构,比如 Counter, defaultdict, OrderedDict,
deque, namedtuple 等,其中最常用的就是 Counter, deque, defaultdict。Counter 顾名思义,是一个计数器,
继承自内置的 dict,常用的方法除了与 dict 相应的方法之外,就是 most_common 了。
1 | >>> from collections import Counter |
下面这段代码,用于统计一段文本中每个单词的使用频率:
1 | >>> from collections import Counter |
Deque
Python 中 deque 是双端队列,可以从前后两端添加或删除元素,且都是线程安全的,时间复杂的都近似O(1)。
虽然 list 也都支持类似的操作,但 list 内部为固定长度的列表操作做了优化,而且对 list 执行 pop(0)
和 insert(0, value) 会在内存中移动原来的整个 list。
1 | !/usr/bin/env python -tt |
其输出结果:
1 | type operation time(s) |
Defaultdict
除了对试图获取一个不存在的键时进行了异常处理(由函数 dafault_factory 提供一个默认值)外,defaultdict 几乎与 Python 内置的 dict 完全一致。
事实上,Python 内置的 dict 也可以通过 setdfault 方法实现类似功能。
1 | >>> from collections import defaultdict |
通过,扩展内置 dict 的一种实现:
1 | >>> class MyDict(dict): |
Array
在 array 模块里定义了一种新的数据结构 array,功能长得跟 list 很像,但保存在
其中的元素必须是相同类型的,因而在存储效率上大大高于 list。尽管如此,对 array
的操作都不会比 list 相应的操作快。另外,需要注意的是,当对 array 做列表推导
时,会自动将整个 array 转换成 list,而用 generator expression 则可以避免。
1 | >>> from array import array |
当 array 的 size 非常大时,对其元素进行就地(in-plaace)操作,很有助于节省存储空间,
通常用 enumerate 来实现。
1 | >>> from array import array |
对于大 array, 就地修改元素的值,比用 generator expression 创建一个新 array
大约能快 15% 。
那么,思考一下,何时需要用到 array 呢?
Heapq
Bisect
Weakref
Copy
Pprint
Singly Linked-List
参考资料: