1. 程式人生 > 其它 >python----collections模組記錄(defaultdict, namedtuple, ChainMap)

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