Go through Python collections
过一遍可能有用的代码和函数,这样在需要类似功能的时候就能够想起来并查询使用。如果每次只是看到了就查一下,自己不会太在意,也不会留下深刻的印象,那么只是认识了这些代码和函数,而不会真正地为自己所用。
Python 的 collections 模块提供 specialized container datatypes 来增强通用目的的内置容器:dict, list, set 和 tuple.
Datatype | Descriptions |
---|---|
namedtuple() |
factory function for creating tuple subclasses with named fields |
deque |
list-like container with fast appends and pops on either end |
ChainMap |
dict-like class for creating a single view of multiple mappings |
Counter |
dict subclass for counting hashable objects |
OrderedDict |
dict subclass that remembers the order entries were added |
defaultdict |
dict subclass that calls a factory function to supply missing values |
UserDict |
wrapper around dictionary objects for easier dict subclassing |
UserList |
wrapper around list objects for easier list subclassing |
UserString |
wrapper around string objects for easier string subclassing |
reference: collections — Container datatypes — Python 3.11.4 documentation
Improving Code Readability: namedtuple()
nametuple()
是 tuple subclasses with named fields,
可以通过 dot notation
的方式直接访问元组中的值,例如:obj.arr
,
从而增强代码的可读写性。在需要使用的 tuple 具有多个 items
并且构造位置和使用位置距离比较远时,将 tuple 换作 nametuple 最佳。
collections.namedtuple(typename, field_names, *, rename=False, defaults=None, module=None)
:
typename
是创建的 nametuple 的名字,要求是有效命名的字符串field_name
是 the list of field names,用来访问 tuple 中元素可是以下几种 string 相关对象:
- 可迭代的字符串对象,例如:
["field1", "field2", "field3]
- a string with whitespace-separated field names, such
as:
"field1 field2 field3"
- a string with comma-separated field names, such as
field1, field2, field3
- a generator expression as field names, such as
(field for field in "xy")
- 可迭代的字符串对象,例如:
1 | In [3]: from collections import * |
2D point
1 | In [7]: Point = namedtuple("Point", ['x', 'y']) # Use a list of strings as field names |
tuple 是不可变对象, namedtuple 可以通过 _replace
来改变值。
1 | In [15]: Person = namedtuple("Person", "name job", defaults = ['python developer']) |
Counter
1 | collections.Counter([iterable-or-mapping]) A Counter is a dict subclass for counting hashable objects. |
传入的参数需要是可迭代对象或者映射,例如:字典,列表,元组等
1 | In [47]: Counter([1,3,3,5,1]) |
Counter 实际上是使用 for 循环和字典进行计数的封装版,返回字典。
1 | In [36]: a = Counter(word) |
Handling Missing Keys: defaultdict
python 字典直接访问不存在的 key 会保存,因此可以使用 dict 自带的函数 get() 来访问,不存在的 key 会返回 None
1 | In [62]: a = {"name": "Jone", "job": "developer"} |
class collections.defaultdict(default_factory=None[,{key1:value1,..}])
defaultdict
相对于 dict 增加的两个功能: 1. 访问不存在的
key 不报错 2. 不存在的 key 的,返回预先定义的默认值
1 | In [82]: b = [("red", 2), ("blue", 4), ('yellow', 8), ('red',5)] |
Keeping Your Dictionaries Ordered: OrderedDict
OrderedDict
:
- 具备每个 key-value pair 的插入顺序,可以在注重顺序的情况下发挥作用
- 提供了
.move_to_end()
,popitem()
方法来操作 pair 的顺序。次卧 - 在比较两个 orderdict 时,比较元素与顺序,二者都相同才可。
1 | In [87]: letters = OrderedDict(b=3, c = 4, e=2, a=5) |
Chaining Dictionaries Together: ChainMap
ChainMap 可以容纳多个 mapping/dictionaries, 并比创建一个字典,然后再多次 update() 更新的速度快. 它是一个可变的视图,updateable views. 对其进行的修改都会影响到对应的 dictionary。
class collections.ChainMap(*maps)
应用场景 1:多个上下文,变量等具有 access priority 的情况:
1 | In [93]: cmd_proxy = {} |
还有一系列的函数,如 .map
返回内部所有的字典的列表。此外还可以对其进行 dict 的操作,只是这些针对
dict 的操作,都只针对第一个 dictionary,例如 .pop()
,
clear()
1 | In [105]: config.maps |
deque
deque: double ended queue,提供双端队列
主要有 append, pop, popleft, extend, extendleft 等方法
1 | In [113]: d = deque() |