递归遍历多维字典,维度未知

17 投票
9 回答
25191 浏览
提问于 2025-04-16 05:00

我想写一个函数,能够递归地遍历一个多维字典,而这个字典的维度是未知的。

这是我目前想到的代码,但似乎有些问题。它会把一些键值对打印两次,而且顺序也不对。

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

撰写回答