[英]Comparing nested dictionaries
我想比較嵌套字典如下:
d = {'siteA': {'00000000': 3, '11111111': 4, '22222222': 5},
'siteB': {'00000000': 1, '11111111': 2, '22222222': 5}}
e = {'siteA': {'00000000': 5}}
f = {'siteB': {'33333333': 10}}
g = {'siteC': {'00000000': 8}}
d
是用於與e
, f
和g
進行比較的完整詞典的總數。
如果e
恰巧在siteA-00000000中找到,那么我希望兩個值(在這種情況下為3和5)加起來成為8。
如果未找到f
(在這種情況下為true),我想將字典追加到d['siteB']
。
如果找不到g
則想追加到d
。
謝謝!
collections.Counter
可用於對字典中的值求和並在不存在的鍵處添加鍵。 由於Counter
是dict
的子類,因此不應中斷其他操作。 除了一次性轉換成本外,它高效且專為此類任務而設計。
from collections import Counter
# convert d to dictionary of Counter objects
d = {k: Counter(v) for k, v in d.items()}
# add items from e
for k, v in e.items():
if k in d:
d[k] += Counter(e[k])
# add item from f if not found
for k, v in f.items():
if k not in d:
d[k] += Counter(f[k])
# add item from g if not found
for k, v in g.items():
if k not in d:
d[k] = Counter(v)
結果:
print(d)
{'siteA': Counter({'00000000': 8, '11111111': 4, '22222222': 5}),
'siteB': Counter({'00000000': 1, '11111111': 2, '22222222': 5}),
'siteC': Counter({'00000000': 8})}
您可以將collections
中的Counter
與defaultdict
結合使用。
顧名思義,計數器對相同的元素進行計數,並且defaultdict允許您通過提供默認值(在這種情況下為空Counter
)來訪問不存在的鍵。 然后您的代碼成為
from collections import Counter, defaultdict
d = defaultdict(Counter)
d['siteA'] = Counter({'00000000': 3, '11111111': 4, '22222222': 5})
d['siteB'] = Counter({'00000000': 1, '11111111': 2, '22222222': 5})
print(d.items())
> dict_items([('siteA', Counter({'22222222': 5, '11111111': 4, '00000000': 3})),
> ('siteB', Counter({'22222222': 5, '11111111': 2, '00000000': 1}))])
# d + e:
d['siteA'].update({'00000000': 5})
print(d.items())
> dict_items([('siteA', Counter({'00000000': 8, '22222222': 5, '11111111': 4})),
> ('siteB', Counter({'22222222': 5, '11111111': 2, '00000000': 1}))])
# d + f
d['siteB'].update({'33333333': 10})
print(d.items())
> dict_items([('siteA', Counter({'00000000': 8, '22222222': 5, '11111111': 4})),
> ('siteB', Counter({'33333333': 10, '22222222': 5, '11111111': 2, '00000000': 1}))])
# d + g
d['siteC'].update({'00000000': 8})
print(d.items())
> dict_items([('siteA', Counter({'00000000': 8, '22222222': 5, '11111111': 4})),
> ('siteB', Counter({'33333333': 10, '22222222': 5, '11111111': 2, '00000000': 1})),
>. ('siteC', Counter({'00000000': 8}))])
假設給定字典dict [site] [address]的格式,此合並函數將從dictFrom中獲取值,並根據您的規則將其插入dictTo中。
def merge(dictTo, dictFrom):
for site in dictFrom:
if site not in dictTo:
dictTo[site] = {}
for address in dictFrom[site]:
dictTo[site][address] = dictTo[site].get(address, 0) + dictFrom[site][address]
merge(d, e)
merge(d, f)
merge(d, g)
這可能比jpp的答案更好,因為dict [site]上的對象仍然都是基本dict。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.