How to iterate over a dictionary with more than three sublevels of dictionaries inside it

I am trying to iterate over a dictionary where some keys have other dictionaries as values, and some of these values ​​are the key for the dictionary that it has as the value. I am parsing a YAML file with over 5000 lines using pyyaml. When I load it, it creates a dictionary of everything in the file and breaks all the auxiliary levels into its own dictionaries.

Here is what I use now, which gives me only the keys and values ​​of things that are not dictionaries themselves, but the keys and meanings of dictionaries:

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) 

Where 'eng' is the highest level that contains everything else in it in the YAML file. Below is a small part of the YAML file. The actual file has over 5,000 lines though

 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.. 

This happens and so on. Some keys have only meanings, some keys have dictionaries, which themselves have dictionaries, and this can go to several levels. I'm just wondering if there is a better and simpler way to do this, then I process it with all the for loops, and if the statements check if this is a dict or not. In the end, I would just need something like this:

 v1: USA v2: Canada v3: Mexico value4: "some text here" value6: "some text here" value7: " some other text here" value8: "some text here" 
+4
source share
1 answer

It looks like you want a solution with recursion:

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

Note: recursion will lead to a stack overflow if you go too deep. However, the limit is usually much higher than you expect here:

 >>> 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 

However, if you are writing a program in which it would be a problem that someone could maliciously create a file and compromise your parser (throw an exception), you should consider converting recursion into iteration, which is always possible. The tradeoff is that recursive code is very easy to read and write, and iterative conversion is sometimes a little less.

+8
source

Source: https://habr.com/ru/post/1485671/


All Articles