Iterating over nested dictionaries (Pythonic)

Asked

Viewed 2,340 times

3

I always lag behind when it comes to thinking of nested repeat loops to iterate over some container (typical of C/C++), because I know that python has very particular ways of iterating over containers. To iterate over dictionaries dictionaries I can only think of the solution nesting loops as in:

>>> dic = {'section1': {'key1': 'value1', 'key2':'value2'}, 'section2': {'key3': 'value3', 'key4': 'value4'}}
>>> for x in dic:
...     print(dic[x])
... 
{'key3': 'value3', 'key4': 'value4'}
{'key2': 'value2', 'key1': 'value1'}
>>> for x in dic:
...     for y in dic[x]:
...         print(dic[x][y])
... 
value3
value4
value2
value1

Is there any more "Pythonic" way to do the same? Who knows using a single for

2 answers

4

Another alternative is itertools.chain.from_iterable:

from itertools import chain

dic = {'section1': {'key1': 'value1', 'key2': 'value2'},
       'section2': {'key3': 'value3', 'key4': 'value4'}
      }

valores = chain.from_iterable(map(lambda sec: sec.values(), dic.values()))

for valor in valores:
    print(valor)
    # value1
    # value2
    # value3
    # value4

See DEMO

If you prefer to display values immediately:

print ( list(chain.from_iterable(map(lambda sec: sec.values(), dic.values()))) )
# ['value1', 'value2', 'value3', 'value4']

See DEMO

  • 1

    Our guy, I went down by mistake. I tried to reverse it but it’s asking you to edit it. .

3


There is, yes, several pythonices :P can do:

Way 1

dic = {'section1': {'key1': 'value1', 'key2':'value2'}, 'section2': {'key3': 'value3', 'key4': 'value4'}}
values = [item for sublist in [dic[i].values() for i in dic] for item in sublist]
for val in values:
    print(val)

Explanation:

To get all the values of each dictionary we can do:

values = [dic[i].values() for i in dic] # [['value2', 'value1'], ['value3', 'value4']]

To turn this list into a single list, we do:

values = [item for sublist in values for item in sublist] # ['value4', 'value3', 'value2', 'value1']

More simplicate way:

dic = {'section1': {'key1': 'value1', 'key2':'value2'}, 'section2': {'key3': 'value3', 'key4': 'value4'}}
valuesLists = [dic[i].values() for i in dic]
values = [item for sublist in valuesLists for item in sublist] # transformar numa só lista
for val in values:
    print(val)

Way 2

(in this case maybe this is the one I would choose)

dic = {'section1': {'key1': 'value1', 'key2':'value2'}, 'section2': {'key3': 'value3', 'key4': 'value4'}}
values = [dic[j][i] for j in dic for i in dic[j]]
print('\n'.join(values)) # imprimir um valor por linha, se for so para isto nao e necessario o ciclo for

Up here we make a nested list compreenshion

Way 3

dic = {'section1': {'key1': 'value1', 'key2':'value2'}, 'section2': {'key3': 'value3', 'key4': 'value4'}}
values = []
valuesLists = [values.extend(dic[i].items()) for i in dic]
for k, v in values:
    print(k, v) # aqui imprime, chave valor... Se quiser que imprima só o valor retire o k do print

On top we have the keys too, just for the value:

dic = {'section1': {'key1': 'value1', 'key2':'value2'}, 'section2': {'key3': 'value3', 'key4': 'value4'}}
values = []
valuesLists = [values.extend(dic[i].values()) for i in dic]
for v in values:
    print(v)

If you are running the cycle for just to print, you can achieve the same result by doing instead of the cycle for final:

print('\n'.join(values))

Browser other questions tagged

You are not signed in. Login or sign up in order to post.