递归遍历多维字典,维度未知
我想写一个函数,能够递归地遍历一个多维字典,而这个字典的维度是未知的。
这是我目前想到的代码,但似乎有些问题。它会把一些键值对打印两次,而且顺序也不对。
def walk_dict(d):
for k,v in d.items():
if isinstance(v, dict):
walk_dict(v)
else:
print "%s %s" % (k, v)
这里有一个示例数组:
d = {
'plan_code': 'b',
'quantity': '1',
'account': {
'account_code': 'b',
'username': 'jdoe',
'email': 'jdoe@domain.com',
'first_name': 'b',
'last_name': 'b',
'company_name': 'Company, LLC.',
'billing_info': {
'first_name': 'b',
'last_name': 'b',
'address1': '123 Test St',
'city': 'San Francisco',
'state': 'CA',
'country': 'US',
'zip': '94105',
'credit_card': {
'number': '1',
'year': '2018',
'month': '12',
'verification_value': '123',
},
},
},
}
9 个回答
2
这段代码确实能正确打印出键值对。你能指出哪些数据是重复的吗?根据上面的数据,这些键:
'first_name': 'b',
'last_name': 'b',
出现在两个字典中——一个是'account',另一个是'billing_info'。所以在输出中它们会出现两次。
另外,如果你想让你的字典中的键值对按照某种顺序打印出来,可以使用有序字典。
5
在编程中,有时候我们需要在代码里做一些判断,比如判断一个条件是否成立。如果条件成立,就执行某些操作;如果不成立,就执行其他操作。这种判断通常用“如果”语句来实现。
例如,我们可以用“如果”来检查一个数字是否大于零。如果是,就告诉用户这个数字是正数;如果不是,就告诉用户这个数字是负数或零。这种方式让我们的程序能够根据不同的情况做出不同的反应。
总之,“如果”语句是编程中非常重要的工具,它帮助我们控制程序的运行逻辑,让程序变得更加智能和灵活。
import json
print(json.dumps(d, indent=4))
20
我不太确定你最终想要达到什么目标,但你的代码是按预期在运行的。你看到的那些看起来像重复的项目,其实是因为有一些键值对,比如 'first_name':'b',它们同时出现在 'account' 和 'billing_info' 这两个地方。我不太清楚你想要什么样的顺序,但字典是无序的,所以你打印它们的函数需要给它们一些顺序,比如可以把下面的内容:
for k,v in d.items():
替换成
for k,v in sorted(d.items(),key=lambda x: x[0]):
或者你可以使用有序字典。你也可以像这样使用 pprint 模块来更好地打印字典:
>>> import pprint
>>> pprint.pprint(d)
{'account': {'account_code': 'b',
'billing_info': {'address1': '123 Test St',
'city': 'San Francisco',
'country': 'US',
'credit_card': {'month': '12',
'number': '1',
'verification_value': '123',
'year': '2018'},
'first_name': 'b',
'last_name': 'b',
'state': 'CA',
'zip': '94105'},
'company_name': 'Company, LLC.',
'email': 'jdoe@domain.com',
'first_name': 'b',
'last_name': 'b',
'username': 'jdoe'},
'plan_code': 'b',
'quantity': '1'}
不过,我不太确定你在这里的最终目标是什么。此外,当值是字典时,你缺少了键。我修改了你的代码,让它做一些类似 pprint 的事情,具体如下:
def walk_dict(d,depth=0):
for k,v in sorted(d.items(),key=lambda x: x[0]):
if isinstance(v, dict):
print (" ")*depth + ("%s" % k)
walk_dict(v,depth+1)
else:
print (" ")*depth + "%s %s" % (k, v)
对于你的示例字典,输出结果是:
>>> walk_dict(d)
account
account_code b
billing_info
address1 123 Test St
city San Francisco
country US
credit_card
month 12
number 1
verification_value 123
year 2018
first_name b
last_name b
state CA
zip 94105
company_name Company, LLC.
email jdoe@domain.com
first_name b
last_name b
username jdoe
plan_code b
quantity 1