如何在所有嵌套字典中循环,以提供连接的所有父关键字及其值


dictionary={' items': { 'heading': 'Maps','description':'Maps123','imagepath':/music/images/','config':{'config1':12,'config2':123}},'db':{'username':'xyz','password':'xyz'},'version':'v1'}

我希望输出格式为:

items/heading: Maps
items/description: Maps123
items/image_path: /music/images/v2/web_api-music.png
items/config/config1: abcd
items/config/config2: hello
db/username: xyz
db/password: xyz
version: v1

script0的答案会产生一个以正斜杠(/(开头的输出。我稍微修改了script0的代码:

def flatten(x, parent=''):
for key in x.keys():
if isinstance(x[key], dict) and parent == '': flatten(x[key], key)
elif isinstance(x[key], dict) and parent != '': flatten(x[key], f"{parent}/{key}")
elif not isinstance(x[key], dict) and parent == '': print(f"{key}: {x[key]}")
else: print(f"{parent}/{key}: {x[key]}")
dictionary= {'items': { 'heading': 'Maps','description':'Maps123','imagepath':'/music/images/','config':{'config1':12,'config2':123}},'db':{'username':'xyz','password':'xyz'},'version':'v1'}
flatten(dictionary)

输出(无前导/(:

items/heading: Maps
items/description: Maps123
items/imagepath: /music/images/
items/config/config1: 12
items/config/config2: 123
db/username: xyz
db/password: xyz
version: v1

请注意,您还可以创建一个新的字典,以输出的左侧为键,右侧为值。

例如:

new_dict = {}
def flatten(x, parent=''):
for key in x.keys():
if isinstance(x[key], dict) and parent == '': flatten(x[key], key)
elif isinstance(x[key], dict) and parent != '': flatten(x[key], f"{parent}/{key}")
elif not isinstance(x[key], dict) and parent == '': new_dict[key] = x[key]
else: new_dict[f"{parent}/{key}"] = x[key]
dictionary= {'items': { 'heading': 'Maps','description':'Maps123','imagepath':'/music/images/','config':{'config1':12,'config2':123}},'db':{'username':'xyz','password':'xyz'},'version':'v1'}
flatten(dictionary)
print(new_dict)

输出:

{'items/heading': 'Maps', 'items/description': 'Maps123', 'items/imagepath': '/music/images/', 'items/config/config1': 12, 'items/config/config2': 123, 'db/username': 'xyz', 'db/password': 'xyz', 'version': 'v1'}

递归函数最适合这样做。它只需要检查参数的类型并向下传递一条密钥路径:

def paths(D,P=[]):
if isinstance(D,dict):
return {p:v for k,d in D.items() for p,v in paths(d,P+[k]).items()} 
else:
return {"/".join(P):D}

输出:

print(paths(dictionary))
{'items/heading': 'Maps',
'items/description': 'Maps123',
'items/imagepath': '/music/images/',
'items/config/config1': 12,
'items/config/config2': 123,
'db/username': 'xyz',
'db/password': 'xyz',
'version': 'v1'}

为了提高效率,您可以将函数作为生成器,并只在末尾从提取的元组中创建一个字典。

def paths(D,P=[]):
if isinstance(D,dict):
yield from ((p,v) for k,d in D.items() for p,v in paths(d,P+[k])) 
else:
yield ("/".join(P),D)

dictionary = dict(paths(dictionary))

检查:

def flatten(x, parent=''):
for key in list(x.keys()):
if( type(x[key]) is dict ):
flatten(x[key], parent+'/'+str(key))
else:
print(parent+'/'+str(key)+': ' + str(x[key]))
dictionary={'items': { 'heading': 'Maps','description':'Maps123','imagepath':'/music/images/','config':{'config1':12,'config2':123}},'db':{'username':'xyz','password':'xyz'},'version':'v1'}
flatten(dictionary)

相关内容

最新更新