Nested dictionary comprehension python

46,732

Solution 1

{inner_k: myfunc(inner_v)} isn't a dictionary comprehension. It's just a dictionary.

You're probably looking for something like this instead:

data = {outer_k: {inner_k: myfunc(inner_v) for inner_k, inner_v in outer_v.items()} for outer_k, outer_v in outer_dict.items()}

For the sake of readability, don't nest dictionary comprehensions and list comprehensions too much.

Solution 2

Adding some line-breaks and indentation:

data = {
    outer_k: {inner_k: myfunc(inner_v)} 
    for outer_k, outer_v in outer_dict.items()
    for inner_k, inner_v in outer_v.items()
}

... makes it obvious that you actually have a single, "2-dimensional" dict comprehension. What you actually want is probably:

data = {
    outer_k: {
        inner_k: myfunc(inner_v)
        for inner_k, inner_v in outer_v.items()
    } 
    for outer_k, outer_v in outer_dict.items()
}

(which is exactly what Blender suggested in his answer, with added whitespace).

Solution 3

{ok: {ik: myfunc(iv) for ik, iv in ov.items()} for ok, ov in od.items()}  

where
ok-outer key
ik-inner key
ov-outer value
iv-inner value od-outer dictionary This is how i remember.

Share:
46,732
Turtles Are Cute
Author by

Turtles Are Cute

Updated on December 27, 2020

Comments

  • Turtles Are Cute
    Turtles Are Cute over 3 years

    I'm having trouble understanding nested dictionary comprehensions in Python 3. The result I'm getting from the example below outputs the correct structure without error, but only includes one of the inner key: value pairs. I haven't found an example of a nested dictionary comprehension like this; Googling "nested dictionary comprehension python" shows legacy examples, non-nested comprehensions, or answers solved using a different approach. I may be using the wrong syntax.

    Example:

    data = {outer_k: {inner_k: myfunc(inner_v)} for outer_k, outer_v in outer_dict.items() for inner_k, inner_v in outer_v.items()}
    

    This example should return the original dictionary, but with the inner value modified by myfunc.

    Structure of the outer_dict dictionary, as well as the result:

    {outer_k: {inner_k: inner_v, ...}, ...}
    
  • Turtles Are Cute
    Turtles Are Cute almost 11 years
    Thank you very much - if this helps anyone, here's a point that confused me: Blender's solution has two changes from my ex: a moved bracket, and putting the inner 'for' before the outer. I originally had the for clause set correctly, but with the bracket in the wrong place, was getting "NameError: global name 'outer_v" is not defined." Then the same error with the 'for's in the wrong location with the bracket in the correct place.
  • Turtles Are Cute
    Turtles Are Cute almost 11 years
    Also very helpful. I'll look into comparing this with using a dict comp for 1 axis within a for loop, as well as the best way to break it up by line, aesthetically.
  • Michael
    Michael over 5 years
    What if the outer_k key value is actually inner_k?
  • Alexander Cska
    Alexander Cska about 5 years
    @ZeroPiraeus is it possible to filter a specific dimension. Say I have a dict[dim1,dim2] where 'dim1=['a','b',c]' and dim2=[1,2] and I would like to get a new dict containing all values of dim1 and only dim2=1. Each value dict[dim1,dim2] is an array. I figured out [ v for k,v in dict.items() if 'a' in k] but this returns a 2d list an I would like to have 1d list.