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