如何在字典中循环使用超过3个字典的子级别

Ale*_* Y. 4 python dictionary nested

我试图循环一个字典,其中一些键有其他字典作为值,其中一些值是它作为值的字典的键.我正在使用pyyaml解析超过5000行的YAML文件.当我加载它时,它会创建文件中所有内容的字典,并将所有子级别分解为自己的字典.

这就是我现在正在使用的东西,它让我只是字典本身的键和值,而不是词典的键和值:

for k1,v1 in dataMap['eng'].items():
    if type(dataMap['eng'][k1]) == dict:
        for k2, v2 in dataMap['eng'][k1].items():
            if type(dataMap['eng'][k1][k2]) == dict:
                for k3, v3 in dataMap['eng'][k1][k2].items():
                    if type(dataMap['eng'][k1][k2][k3]) == dict:
                        print "key: {}, val: {}".format(k3, v3)
                    else:
                        print "key: {}, val: {}".format(k3, v3)
            else:
                print "key: {}, val: {}".format(k2, v2)
    else:
        print "key: {}, val: {}".format(k1, v1)
Run Code Online (Sandbox Code Playgroud)

其中'eng'是最高级别,它在YAML文件中包含其中的所有其他内容.下面是我正在使用的YAML文件的一个小部分.实际文件中有超过5000行

eng:
  value1: 
    v1: USA
    v2: Canada
    v3: Mexico
  value2:
    value3:
       value4: "some text here"
       value5:
          value6: "some text here"
          value7: " some other text here"
       value8: "some text here"
    etc..
Run Code Online (Sandbox Code Playgroud)

它继续这样下去.有些键只有值,有些键有字典本身有字典,这可以在几个层次上深入.我只是想知道是否有更好更简单的方法来实现这一点然后他们用所有for循环和if语句检查它是否是一个字典来处理它.最后我只需要这样的东西:

v1: USA
v2: Canada
v3: Mexico
value4: "some text here"
value6: "some text here"
value7: " some other text here"
value8: "some text here"
Run Code Online (Sandbox Code Playgroud)

svk*_*svk 8

听起来你想要一个使用递归的解决方案:

def recurse( x ):
  for k, v in x.items():
    if isinstance( v , dict ):
      recurse( v )
    else:
      print "key: {}, val: {}".format(k, v) 
Run Code Online (Sandbox Code Playgroud)

请注意,如果过深,递归将导致堆栈溢出.但是,限制通常比您在此处预期的要高得多:

>>> import sys
>>> sys.getrecursionlimit()
1000
>>> def f(i):
      f(i+1)
>>> f(1)
...
File "<stdin>", line 3, in f
File "<stdin>", line 3, in f
File "<stdin>", line 3, in f
RuntimeError: maximum recursion depth exceeded
Run Code Online (Sandbox Code Playgroud)

但是,如果您正在编写一个程序,其中某人可能会恶意制作文件并使您的解析器崩溃(引发异常),那么您应该考虑将递归转换为迭代,这始终是可能的.权衡是递归代码非常容易读写,迭代转换有时会略微减少.