[英]How to merge nested dictionaries?
我有一個嵌套字典列表(python 3.9),看起來像這樣:
records = [
{'Total:': {'Owner:': {'Available:': {'15 to 34 years': 1242}}}},
{'Total:': {'Owner:': {'Available:': {'35 to 64 years': 5699}}}},
{'Total:': {'Owner:': {'Available:': {'65 years and over': 2098}}}},
{'Total:': {'Owner:': {'No Service:': {'15 to 34 years': 43}}}},
{'Total:': {'Owner:': {'No Service:': {'35 to 64 years': 64}}}},
{'Total:': {'Owner:': {'No Service:': {'65 years and over': 5}}}},
{'Total:': {'Renter:': {'Available:': {'15 to 34 years': 1403}}}},
{'Total:': {'Renter:': {'Available:': {'35 to 64 years': 2059}}}},
{'Total:': {'Renter:': {'Available:': {'65 years and over': 395}}}},
{'Total:': {'Renter:': {'No Service:': {'15 to 34 years': 16}}}},
{'Total:': {'Renter:': {'No Service:': {'35 to 64 years': 24}}}},
{'Total:': {'Renter:': {'No Service:': {'65 years and over': 0}}}},
]
嵌套級別並不總是一致的。 上面的示例有 4 個級別(總、所有者/租用者、可用/無服務、年齡組),但有些示例只有一個級別,而其他示例則多達 5 個級別。
我想以一種不會像update()
或{*dict_a, **dict_b}
那樣替換最終字典的方式合並數據。
最終的 output 應如下所示:
combined = {
'Total': {
'Owner': {
'Available': {
'15 to 34 years': 1242,
'35 to 64 years': 5699,
'65 years and over': 2098
},
'No Service:': {
'15 to 34 years': 43,
'35 to 64 years': 64,
'65 years and over': 5
}
},
'Renter': {
'Available': {
'15 to 34 years': 1403,
'35 to 64 years': 2059,
'65 years and over': 395
},
'No Service:': {
'15 to 34 years': 16,
'35 to 64 years': 24,
'65 years and over': 0
}
},
}
}
遞歸是一種在任意嵌套結構上導航和操作的簡單方法:
def combine_into(d: dict, combined: dict) -> None:
for k, v in d.items():
if isinstance(v, dict):
combine_into(v, combined.setdefault(k, {}))
else:
combined[k] = v
combined = {}
for record in records:
combine_into(record, combined)
print(combined)
{'Total:': {'Owner:': {'Available:': {'15 to 34 years': 1242, '35 to 64 years': 5699, '65 years and over': 2098}, 'No Service:': {'15 to 34 years': 43, '35 to 64 years': 64, '65 years and over': 5}}, 'Renter:': {'Available:': {'15 to 34 years': 1403, '35 to 64 years': 2059, '65 years and over': 395}, 'No Service:': {'15 to 34 years': 16, '35 to 64 years': 24, '65 years and over': 0}}}}
這里的一般想法是,對combine_into
的每次調用都采用一個 dict 並將其組合到combined
dict 中——每個本身就是 dict 的值都會導致另一個遞歸調用,而其他值只是按原樣復制到combined
中。
請注意,如果某些records
對特定節點是否為葉子存在分歧,這將引發異常(或破壞某些數據)!
對於這個特定的例子,一種更直接的組合方式。
out = {}
for dct1 in records:
for k1, dct2 in dct1.items():
for k2, dct3 in dct2.items():
for k3, dct4 in dct3.items():
out.setdefault(k1,{}).setdefault(k2,{}).setdefault(k3,{}).update(dct4)
將比遞歸 function 更快,但必須根據嵌套的深度進行更新。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.