locke14
locke14

Reputation: 1375

3 level nested dictionary comprehension in Python

I have a Python dictionary as follows:

d = {'1': {'1': 3, '2': 1, '3': 1, '4': 4, '5': 2, '6': 3},
     '2': {'1': 3, '2': 3, '3': 1, '4': 2},
     '3': {'1': 1, '2': 1, '3': 3, '4': 2, '5': 1, '6': 1, '7': 1},
     '4': {'1': 1, '2': 1, '3': 3, '4': 2, '5': 1, '6': 1, '7': 1}}

I have this operation on the dictionary:

D = {}
for ko, vo in d.items():
  for ki, vi in vo.items():
    for i in range(vi):
      D[f'{ko}_{ki}_{i}'] = someFunc(ko, ki, i)

I want to translate it into a one liner with dictionary comprehension as follows:

D = {f'{ko}_{ki}_{i}': someFunc(ko, ki, i) for i in range(vi) for ki, vi in vo.items() for ko, vo in d.items()}

But I get an error

NameError: name 'vi' is not defined

Can someone help me with the correct syntax for achieving this?

Upvotes: 0

Views: 1223

Answers (2)

Karl Knechtel
Karl Knechtel

Reputation: 61526

The for clauses in the list comprehension should appear in the same order as in the equivalent for-loop code. The only thing that "moves" is that the innermost assignment is replaced by an expression at the beginning.

Please see https://treyhunner.com/2015/12/python-list-comprehensions-now-in-color/ for details.

Upvotes: 1

DaveIdito
DaveIdito

Reputation: 1606

The order of the loops has to be reversed.

This is what you're looking for:

D = {f'{ko}_{ki}_{i}': someFunc(ko, ki, i) for ko, vo in d.items() for ki, vi in vo.items() for i in range(vi)  }

Upvotes: 1

Related Questions