2

I have a dict with list values, like this:

d = {'number': [1, 2], 'letter': ['a', 'b']}

I need to full join those lists, so I do:

keys = list(d.keys())

r = [
    {keys[0]: v1, keys[1]: v2}
    for v1 in d[keys[0]]
    for v2 in d[keys[1]]
]

This delivers the desired result:

[{'number': 1, 'letter': 'a'}, {'number': 1, 'letter': 'b'}, {'number': 2, 'letter': 'a'}, {'number': 2, 'letter': 'b'}]

How do I scale this solution for a case of 3 or more lists? For example if I need to process a dict of 3 lists:

d = {'number': [1, 2], 'letter': ['a', 'b'], 'sign': ['!', '.']}

How to do this in case I don't know the number of lists inside the dict?

prupru
  • 135
  • 6

1 Answers1

2

IIUC, use itertools.product like this:

>>> from itertools import product
>>> d = {'number': [1, 2], 'letter': ['a', 'b']}
>>> [dict(zip(d, vs)) for vs in product(*d.values())]
[{'number': 1, 'letter': 'a'}, {'number': 1, 'letter': 'b'}, {'number': 2, 'letter': 'a'}, {'number': 2, 'letter': 'b'}]
timgeb
  • 76,762
  • 20
  • 123
  • 145
  • 1
    Thanks! I actually needed a cartesian product, just didn't know what it is called. – prupru Feb 11 '22 at 12:52
  • is it guaranteed that zip(d, vs) will take dictionary items in the same order as product(*(d.values))? I mean, zip can take 'number' key first but product() will place letters first so we can end up with number keys paired with letters. – prupru Feb 11 '22 at 16:11
  • 1
    @prupru see [this](https://stackoverflow.com/questions/835092/python-dictionary-are-keys-and-values-always-the-same-order) – timgeb Feb 12 '22 at 14:56