![](/img/trans.png)
[英]How to flat nested dict keys and values into flat lists of their types and variables?
[英]how to transfer this flat dict to a nested dict?
有一個簡單的字典,像這樣:
{"a.b": "foo", "a.c": "bar", "d.e.f":"baz"}
以及如何使用Python將dict轉移到此:
{
"a":
{
"b": "foo",
"c": "bar"
},
"d":
{
"e":
{
"f": "baz"
}
}
}
您可以在上split
鍵.
到最后一個值以及之前的所有內容:
*parents, key = k.split('.')
您可以使用類似以下內容的內容來挖掘嵌套字典(如有必要,可以創建它們):
end = reduce(lambda x, y: x.setdefault(y, {}) , parents, new_d)
在這里end
將是鏈末尾的字典。 因此,此時您只需分配值即可。 就像是:
from functools import reduce
d = {"a.b": "foo", "a.c": "bar", "d.e.f":"baz", "d.e.g":"M", 'l':"single_key_test" }
new_d = {}
for k in d:
*parents, key = k.split('.')
end = reduce(lambda x, y: x.setdefault(y, {}) , parents, new_d)
end[key] = d[k]
print(new_d)
結果:
{'a': {'b': 'foo', 'c': 'bar'}, 'd': {'e': {'f': 'baz', 'g': 'M'}}, 'l': 'single_key_test'}
首先,您必須將鍵分割為'.'
獲得路徑。
然后,您可以創建一個從一個路徑創建嵌套字典的函數:
def make_nested_dict(iterable, final):
"""Make nested dict from iterable"""
if iterable:
head, *tail = iterable
return {head: make_nested_dict(tail, final)}
else:
return final
其工作原理如下:
d = {"a.b": "foo", "a.c": "bar", "d.e.f":"baz"}
for key in d:
paths = key.split('.')
nested_path = make_nested_dict(paths, d[key])
print(nested_path)
並給出以下路徑:
{'a': {'b': 'foo'}}
{'a': {'c': 'bar'}}
{'d': {'e': {'f': 'baz'}}}
然后,您可以創建一個將兩個嵌套字典遞歸合並的函數:
def merge_nested_dicts(d1, d2):
"""Merge two nested dictionaries together"""
for key in d2:
if key in d1:
if isinstance(d2[key], dict) and isinstance(d1[key], dict):
merge_nested_dicts(d1[key], d2[key])
else:
d1[key] = d2[key]
return d1
您可以通過更新結果嵌套的dict進行合並:
nested_dict = {}
for key in d:
paths = key.split('.')
nested_path = make_nested_dict(paths, d[key])
nested_dict = merge_nested_dicts(nested_dict, nested_path)
print(nested_dict)
現在,這給出了以下內容:
{'a': {'b': 'foo', 'c': 'bar'}, 'd': {'e': {'f': 'baz'}}}
帶有一些注釋的完整代碼:
def make_nested_dict(iterable, final):
"""Make nested dictionary path with a final attribute"""
# If iterable, keep recursing
if iterable:
# Unpack key and rest of dict
head, *tail = iterable
# Return new dictionary, recursing on tail value
return {head: make_nested_dict(tail, final)}
# Otherwise assign final attribute
else:
return final
def merge_nested_dicts(d1, d2):
"""Merge two nested dictionaries together"""
for key in d2:
# If we have matching keys
if key in d1:
# Only merge if both values are dictionaries
if isinstance(d2[key], dict) and isinstance(d1[key], dict):
merge_nested_dicts(d1[key], d2[key])
# Otherwise assign normally
else:
d1[key] = d2[key]
return d1
if __name__ == "__main__":
d = {"a.b": "foo", "a.c": "bar", "d.e.f":"baz", "d.e.g":"M", 'l':"single_key_test" }
nested_dict = {}
for key in d:
# Create path
paths = key.split('.')
# Create nested path
nested_path = make_nested_dict(paths, d[key])
# Update result dict by merging with new dict
nested_dict = merge_nested_dicts(nested_dict, nested_path)
print(nested_dict)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.