对于 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
参考资料: