collections

 

2022-12-15


  • #ChainMap : 类似字典的容器

  • #Counter : 字典的子类, 可以计算

  • #defaultdict : 字典的子类, 为字典的键提供一个默认值

  • #namedtuple : 命名元组

  • deque: 双端队列
  • OrderedDict: 记住字典中键增加的顺序

ChainMap

无需合并便可以把多个容器链接在一起,以作为一个容器去处理。

1
import collections
2
3
a = {"a": "A", "b": "42"}
4
b = {"b": "B", "d": "D",}
5
6
m = collections.ChainMap(a, b)
7
m["b"] # 返回 42
8
list(m.keys()) # 返回['b', 'd', 'a']
9
list(m.values()) # 返回['42', 'D', 'A']

ChainMap 映射的数据是可变的,更新对应字典的值会直接反应的映射中。

1
# 修改 b 值为 B,字典 a 和 m 的值会同步被修改
2
m["b"] = "B"
3
4
# 如果不想再原表上做修改,可以使用 new_child() 方法
5
m2 = m1.new_child()
6
# 这样修改 m2 的值不会影响到 m 和原字典。
7
# m2 返回: ChainMap({'b': 24}, {'a': 'A', 'b': '42'}, {'b': 'B', 'd': 'D'})

.new_child() 会在列表的最前面新增一个字典。

Counter

1
# 用下面三种方式创建的结果都是一样的
2
# 第一种会自动计算重复出现的次数, 用元组也可以
3
collections.Counter(["a", "b", "a", "b", "c", "b"])
4
collections.Counter({"a": 2, "b":3, "c": 1})
5
collections.Counter(a=2, b=3, c=1)
6
# 返回: Counter({'b': 3, 'a': 2, 'c': 1})

和其他数据结构一样,也支持新建一个空的:

1
cc = collections.Counter() # 返回: Counter()
2
# 可以使用 update 增加元素
3
cc.update(("a", "a")) # 返回 Counter({'a': 2})

访问的方式可以字典一样, 不过如果访问的键不存在,会返回 0:

1
cc.["a"] # 返回 2
2
cc.["z"] # 返回 0

另外 .elements

会以 迭代器 的方式返回所有的元素:

1
(cc.elements())
2
["a", "a"]

也可以直接统计次数最高的元素:

1
cc = collections.Counter(["a", "b", "a", "b", "c", "b"])
2
3
# 默认返回所有,也支持提供参数,返回指定数量
4
cc.most_common()
5
# 返回: [('b', 3), ('a', 2), ('c', 1)]

3.10 起支持计算总值:

1
cc.total() # 返回

defaultdict

当字典键不存在时,返回默认值:

1
def default_value():
2
return "42"
3
4
d = collections.defaultdict(default_value, {"a": 1, "b": 2})
5
6
print(d["a"]) # 返回 1
7
print(d["c"]) # 返回默认值 42

namedtuple

命名元组

1
import collections
2
3
tup = collections.namedtuple("Tup", "name, age")
4
bob = tup(name="Bob", age="42")
5
6
print(bob) # 返回: Tup(name='Bob', age='42')
7
print(bob.name) # 返回: Bob
8
print(bob[0]) # 返回: Bob