遍历嵌套字典

20 投票
6 回答
28996 浏览
提问于 2025-04-17 07:26

有没有简单的方法可以遍历嵌套字典?这个字典可能里面还包含其他对象,比如列表、元组,甚至又是字典,这样遍历的时候能把这些对象里的所有元素都覆盖到吗?

举个例子,如果我在嵌套字典对象里输入一个键,我希望在Python解释器中能看到所有的内容。


[编辑] 这里是一个示例字典:

{
'key_1': 'value_1',
'key_2': {'key_21': [(2100, 2101), (2110, 2111)],
      'key_22': ['l1', 'l2'],
      'key_23': {'key_231': 'v'},
      'key_24': {'key_241': 502,
             'key_242': [(5, 0), (7, 0)],
             'key_243': {'key_2431': [0, 0],
                 'key_2432': 504,
                 'key_2433': [(11451, 0), (11452, 0)]
                },
             'key_244': {'key_2441': {'key_24411': {'key_244111': 'v_24411',
                                'key_244112': [(5549, 0)]
                               },
                          'key_24412':'v_24412'
                         },
                 'key_2441': ['ll1', 'll2']
                }
            },
     }
}

抱歉让人看不懂,但我已经尽力了。

6 个回答

3

这里有另一个解决方案,

#!/usr/bin/python

d = {'key_1': 'value_1',
     'key_2': {'key_21': [(2100, 2101), (2110, 2111)],
           'key_22': ['l1', 'l2'],
           'key_23': {'key_231': 'v'},
           'key_24': {'key_241': 502,
                      'key_242': [(5, 0), (7, 0)],
                      'key_243': {'key_2431': [0, 0],
                                  'key_2432': 504,
                                  'key_2433': [(11451, 0), (11452, 0)]},
                      'key_244': {'key_2441': ['ll1', 'll2']}}}}

def search_it(nested, target):
    found = []
    for key, value in nested.iteritems():
        if key == target:
            found.append(value)
        elif isinstance(value, dict):
            found.extend(search_it(value, target))
        elif isinstance(value, list):
            for item in value:
                if isinstance(item, dict):
                    found.extend(search_it(item, target))
        else:
            if key == target:
                found.append(value)
    return found

keys = [ 'key_242', 'key_243', 'key_242', 'key_244', 'key_1' ]

for key in keys:
    f = search_it(d, key)
    print 'Key: %s, value: %s' % (key, f[0])

输出结果:

Key: key_242, value: [(5, 0), (7, 0)]
Key: key_243, value: {'key_2433': [(11451, 0), (11452, 0)], 'key_2432': 504, 'key_2431': 
 [0, 0]}
Key: key_242, value: [(5, 0), (7, 0)]
Key: key_244, value: {'key_2441': ['ll1', 'll2']}
Key: key_1, value: value_1
7

这是Graddy在上面提到的recurse()函数的生成器版本,它不会在处理字符串时出错,同时还会给你一个复合键(就像是饼干屑路径一样),让你知道是如何得到某个值的:

def recurse(d, keys=()):
    if type(d) == dict:
         for k in d:
            for rv in recurse(d[k], keys + (k, )):
                yield rv
    else:
        yield (keys, d)

for compound_key, val in recurse(eg_dict):
    print '{}: {}'.format(compound_key, val)

使用问题中提供的示例字典,这段代码会产生以下输出:

('key_1',): value_1
('key_2', 'key_21'): [(2100, 2101), (2110, 2111)]
('key_2', 'key_22'): ['l1', 'l2']
('key_2', 'key_23', 'key_231'): v
('key_2', 'key_24', 'key_241'): 502
('key_2', 'key_24', 'key_243', 'key_2433'): [(11451, 0), (11452, 0)]
('key_2', 'key_24', 'key_243', 'key_2432'): 504
('key_2', 'key_24', 'key_243', 'key_2431'): [0, 0]
('key_2', 'key_24', 'key_242'): [(5, 0), (7, 0)]
('key_2', 'key_24', 'key_244', 'key_2441'): ['ll1', 'll2']

在Python 3中,第二个yield循环可以用yield from来替代。这个生成器可以通过将type(d) == dict的检查替换为isinstance(d, collections.Mapping)来变得更通用,使用collections模块中的Mapping ABC。

19

在编程中,有时候我们需要让程序在特定的条件下执行某些操作。比如说,当用户点击一个按钮时,我们希望程序能做出反应。这个过程就叫做“事件处理”。

事件处理的基本思路是:当某个事件发生时(比如点击、输入等),程序会自动执行我们预先设定好的代码。这就像是给程序设置了一个“监听器”,它会时刻关注这些事件,一旦发生,就会触发相应的反应。

举个简单的例子,想象一下你在家里装了一个门铃。每当有人按门铃的时候,你就会听到声音并去开门。这里的“按门铃”就是事件,而“你去开门”就是事件发生后要执行的操作。

在编程中,我们通常会使用一些特定的语法来定义这些事件和对应的操作。这样,程序就能在合适的时候做出反应,让用户的体验更加流畅和自然。

def recurse(d):
  if type(d)==type({}):
    for k in d:
      recurse(d[k])
  else:
    print d

撰写回答