python---collections模块记录(defaultdict, namedtuple, ChainMap)

collections   ---  defaultdict

对于一个字典或键值,取不存在的键时返回函数提前设置好的默认值。避免取键错误。

 1 import collections
 2 
 3 
 4 def default_factory():
 5     return 'default value'
 6 # ss = {'foo':'bar'}
 7 # d = collections.defaultdict(default_factory,ss)
 8 d = collections.defaultdict(default_factory, foo='bar')
 9 
10 print('d:', d)
11 print('foo =>', d['foo'])
12 print('bar =>', d['bar'])
13 
14 
15 """
16 d: defaultdict(<function default_factory at 0x00000227672D18C8>, {'foo': 'Foo'})
17 foo => Foo
18 bar => default value
19 """

collections   ---  namedtuple

标准tuple使用数字索引可以访问到tuple元素,相较于标准tuple,namedtuple不仅是兼具tuple的特点,还可以通过键值对访问元素。

每种namedtuple都由自己的类表示,该类是使用namedtuple()工厂函数创建的。参数是新类的名称和包含元素名称的字符串(或列表或元组)。

每个namedtuple可以通过  _属性(_方法) 来实现一些功能,如 _replace 替换元素生成新的tuple,_fields 遍历初始化 namedtuple 时的元素名称。(_asdict())

注意:元素名称应尽量避免关键字冲突或重复,否则初始化时会ValueError异常,可以添加rename=True来解决,关键字参数或重复名称会被数字下标代替。

 1 #普通元组
 2 bob = ('Bob', 30, 'male')
 3 print('Representation:', bob)
 4 
 5 jane = ('Jane', 29, 'female')
 6 print('\nField by index:', jane[0])
 7 
 8 print('\nFields by index:')
 9 for p in [bob, jane]:
10     print('{} is a {} year old {}'.format(*p))
11 
12 """
13 Representation: ('Bob', 30, 'male')
14 
15 Field by index: Jane
16 
17 Fields by index:
18 Bob is a 30 year old male
19 Jane is a 29 year old female
20 """
21 
22 
23 
24 #namedtuple
25 
26 import collections
27 
28 Person = collections.namedtuple('Person','name age gender age',rename=True)
29 sam =Person('sam','28','man','24')
30 tom = sam._replace(name='tom')
31 print(*tom)
32 print(*sam)
33 print(sam.name)
34 print(sam._fields)
35 
36 """
37 tom 28 man 24
38 sam 28 man 24
39 sam
40 ('name', 'age', 'gender', '_3')
41 """

collections   ---  ChainMap

通过ChainMap将生成一个新的对象,该对象具有字典的常规操作方法,可以同时遍历两个字典。随着原始字典的改变而动态改变。

子映射按照它们传递给构造函数的顺序进行搜索,因此为键报告的值 'c' 来自 a字典

import collections

a = {'a': 'A', 'c': 'C'}
b = {'b': 'B', 'c': 'D'}

m = collections.ChainMap(a, b)

print('Individual Values')
print('a = {}'.format(m['a']))
print('b = {}'.format(m['b']))
print('c = {}'.format(m['c']))
print()

print('Keys = {}'.format(list(m.keys())))
print('Values = {}'.format(list(m.values())))
print()

print('Items:')
for k, v in m.items():
    print('{} = {}'.format(k, v))
print()

print('"d" in m: {}'.format(('d' in m)))


"""
Individual Values
a = A
b = B
c = C

Keys = ['b', 'c', 'a']
Values = ['B', 'C', 'A']

Items:
b = B
c = C
a = A

"d" in m: False
"""

重新排序

通过实例对象的maps属性可以将映射关系转换为 list ,从而直接添加新映射或更改元素的顺序以控制查找和更新行为。

 1 import collections
 2 
 3 a = {'a': 'A', 'c': 'C'}
 4 b = {'b': 'B', 'c': 'D'}
 5 
 6 m = collections.ChainMap(a, b)
 7 
 8 print(m.maps)
 9 print('c = {}\n'.format(m['c']))
10 
11 # reverse the list
12 m.maps = list(reversed(m.maps))
13 
14 print(m.maps)
15 print('c = {}'.format(m['c']))
16 
17 
18 #键c的value的改变
19 """
20 [{'a': 'A', 'c': 'C'}, {'b': 'B', 'c': 'D'}]
21 c = C
22 
23 [{'b': 'B', 'c': 'D'}, {'a': 'A', 'c': 'C'}]
24 c = D
25 """

更新映射关系

更改父级映射关系子映射会改变,同时通过ChainMap对象的子映射也可以改动父级映射。

 1 import collections
 2 
 3 a = {'a': 'A', 'c': 'C'}
 4 b = {'b': 'B', 'c': 'D'}
 5 
 6 m = collections.ChainMap(a, b)
 7 
 8 print('Before: {}'.format(m['c']))
 9 a['c'] = 'E'
10 print('After : {}'.format(m['c']))
11 
12 print('Before: {}'.format(m['a']))
13 m['a'] = 'AA'
14 print('After : {}'.format(m['a']))
15 
16 print('a {}'.format(a))
17 
18 
19 
20 """
21 Before: C
22 After : E
23 Before: A
24 After : AA
25 a {'a': 'AA', 'c': 'E'}
26 """

创建新实例

maps列表的前面有一个额外的映射,以便轻松避免修改现有的底层数据结构。

这种堆叠行为使得将ChainMap 实例用作模板或应用程序上下文变得很方便。

具体来说,很容易在一次迭代中添加或更新值,然后在下一次迭代中丢弃更改。

 1 import collections
 2 
 3 a = {'a': 'A', 'c': 'C'}
 4 b = {'b': 'B', 'c': 'D'}
 5 
 6 m1 = collections.ChainMap(a, b)
 7 m2 = m1.new_child()
 8 
 9 print('m1 before:', m1)
10 print('m2 before:', m2)
11 
12 m2['c'] = 'E'
13 
14 print('m1 after:', m1)
15 print('m2 after:', m2)
16 
17 
18 #m2的maps列表多了一个新的空映射集
19 """
20 m1 before: ChainMap({'a': 'A', 'c': 'C'}, {'b': 'B', 'c': 'D'})
21 m2 before: ChainMap({}, {'a': 'A', 'c': 'C'}, {'b': 'B', 'c': 'D'})
22 m1 after: ChainMap({'a': 'A', 'c': 'C'}, {'b': 'B', 'c': 'D'})
23 m2 after: ChainMap({'c': 'E'}, {'a': 'A', 'c': 'C'}, {'b': 'B', 'c': 'D'})
24 """

对于新上下文已知或预先构建的情况,也可以将映射传递给new_child()

import collections


a = {'a': 'A', 'c': 'C'}
b = {'b': 'B', 'c': 'D'}
c = {'c': 'E'}

m1 = collections.ChainMap(a, b)

# m2 = collections.ChainMap(c, *m1.maps)  #同样的效果
m2 = m1.new_child(c)

print(m1)
print(m2)

print('m1["c"] = {}'.format(m1['c']))
print('m2["c"] = {}'.format(m2['c']))



"""
ChainMap({'a': 'A', 'c': 'C'}, {'b': 'B', 'c': 'D'})
ChainMap({'c': 'E'}, {'a': 'A', 'c': 'C'}, {'b': 'B', 'c': 'D'})
m1["c"] = C
m2["c"] = E
"""

滴水穿石,好记性不如烂笔头,主要是忘性大 0.0

posted @ 2021-07-22 10:45  ttoia  阅读(39)  评论(0编辑  收藏  举报