循环遍历所有嵌套的字典值?

新手上路,请多包涵
for k, v in d.iteritems():
    if type(v) is dict:
        for t, c in v.iteritems():
            print "{0} : {1}".format(t, c)

我正在尝试遍历字典并打印出值不是嵌套字典的所有键值对。如果该值是一个字典,我想进入它并打印出它的键值对……等等。有什么帮助吗?

编辑

这个怎么样?它仍然只打印一件事。

 def printDict(d):
    for k, v in d.iteritems():
        if type(v) is dict:
            printDict(v)
        else:
            print "{0} : {1}".format(k, v)

完整的测试用例

字典:

 {u'xml': {u'config': {u'portstatus': {u'status': u'good'}, u'target': u'1'},
      u'port': u'11'}}

结果:

 xml : {u'config': {u'portstatus': {u'status': u'good'}, u'target': u'1'}, u'port': u'11'}

原文由 Takkun 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 502
2 个回答

正如 Niklas 所说,你需要递归,即你想定义一个函数来打印你的 dict,如果值是一个 dict,你想使用这个新的 dict 调用你的打印函数。

就像是 :

 def myprint(d):
    for k, v in d.items():
        if isinstance(v, dict):
            myprint(v)
        else:
            print("{0} : {1}".format(k, v))

原文由 Scharron 发布,翻译遵循 CC BY-SA 4.0 许可协议

如果您编写自己的递归实现或与堆栈等效的迭代,则存在 潜在问题。看这个例子:

 dic = {}
dic["key1"] = {}
dic["key1"]["key1.1"] = "value1"
dic["key2"]  = {}
dic["key2"]["key2.1"] = "value2"
dic["key2"]["key2.2"] = dic["key1"]
dic["key2"]["key2.3"] = dic

通常意义上,嵌套字典就是一个n叉树状的数据结构。但该定义 并不排除 交叉边甚至后边(因此不再是树)的可能性。例如,这里的 key2.2 持有来自 key1 的字典, key2.3 指向整个字典(后缘/循环)。当有后沿(循环)时,堆栈/递归将无限运行。

             root<-------back edge
          /      \           |
       _key1   __key2__      |
      /       /   \    \     |
 |->key1.1 key2.1 key2.2 key2.3
 |   /       |      |
 | value1  value2   |
 |                  |
cross edge----------|

如果你用 Scharron 的这个实现打印这本字典

def myprint(d):
    for k, v in d.items():
        if isinstance(v, dict):
            myprint(v)
        else:
            print "{0} : {1}".format(k, v)


你会看到这个错误:

 > RuntimeError: maximum recursion depth exceeded while calling a Python object

senderle 的实现也是如此。

类似地,您可以通过 Fred Foo 的此实现获得无限循环:

 def myprint(d):
    stack = list(d.items())
    while stack:
        k, v = stack.pop()
        if isinstance(v, dict):
            stack.extend(v.items())
        else:
            print("%s: %s" % (k, v))

然而,Python 实际上检测嵌套字典中的循环:

 print dic
{'key2': {'key2.1': 'value2', 'key2.3': {...},
       'key2.2': {'key1.1': 'value1'}}, 'key1': {'key1.1': 'value1'}}

“{…}” 是检测到循环的地方。

根据 Moondra 的要求,这是一种避免循环 (DFS) 的方法:

 def myprint(d):
    stack = list(d.items())
    visited = set()
    while stack:
        k, v = stack.pop()
        if isinstance(v, dict):
            if k not in visited:
                stack.extend(v.items())
        else:
            print("%s: %s" % (k, v))
        visited.add(k)

原文由 tengr 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题