Home > Enterprise >  Unpacking multiple values from a nested dictionary in one line "pythonically"
Unpacking multiple values from a nested dictionary in one line "pythonically"

Time:01-14

Suppose I have a nested dictionary that looks like this:

numbers = { 
    'one': {"square": "one", "cube": "one"},
    'two': {"square": "four", "cube": "eight"},
    'three': {"square": "nine", "cube": "twenty-seven"},
    'four': {"square": "sixteen", "cube": "sixty-four"}
}

and I want to unpack the squares and cubes into lists. I could do this:

squares = [n["square"] for n in numbers.values()]
cubes = [n["cube"] for n in numbers.values()]

but that doesn't seem very satisfactory for the repetitive code. I could also bring in numpy and do this:

import numpy
squares_array, cubes_array = numpy.array([(n["square"],n["cube"]) for n in numbers.values()]).T

and that neatly unpacks everything into numpy arrays, but it looks a little unsatisfactory since I shouldn't need numpy to do this, and taking the transpose at the end is a little weird in my highly subjective opinion. It doesn't seem "pythonic" to me.

So the question is how can I do this in one line without numpy?

CodePudding user response:

squares, cubes = zip(*[(n["square"], n["cube"]) for n in numbers.values()])

CodePudding user response:

You could use zip and a iterator:

squares, cubes = map(list, zip(*(d.values() for d in numbers.values())))

If there are more keys or a different order, specify them manually:

squares, cubes = map(list, zip(*([d['square'], d['cube']]
                                 for d in numbers.values())))

output:

>>> squares
['one', 'four', 'nine', 'sixteen']

>>> cubes
['one', 'eight', 'twenty-seven', 'sixty-four']
  •  Tags:  
  • Related