6

I have a dictionary of lists, like {'a': [1, 2, 3], 'b': [5, 6, 7, 8]}. There may by more than two key/value pairs in the actual data. I want to display an exhaustive list of dictionaries, one per line, where each dictionary has the same keys, and each value is an element chosen from the corresponding original list.

So for this input, the result would look like

{'a': 1, 'b': 5}
{'a': 1, 'b': 6}
...
{'a': 3, 'b': 8}

with a total of 3 * 4 = 12 lines of output.

I can do this for hard-coded key names:

for a, b in itertools.product(*p.itervalues()):
    print({'a':a, 'b':b})

However, for the real data, I don't necessarily know the key names in advance, and there may be an unknown number of key-value pairs.

How can I fix the code so that it produces the desired dicts from the itertools.product, regardless of the keys?

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
mchangun
  • 9,814
  • 18
  • 71
  • 101

1 Answers1

12

Instead of unpacking the product results into separate variables, just zip them with the original keys:

from itertools import product

for i in product(*p.values()):
    print(dict(zip(p, i)))
Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
Jayanth Koushik
  • 9,476
  • 1
  • 44
  • 52
  • I actually have a doubt about this. Is the 'order' going to be the same for both `p.values` and `p.keys`? – Jayanth Koushik Jun 11 '14 at 06:42
  • 1
    I was actually going to answer my own question with that solution but I was unsure on the order of p.keys. I somehow have the feeling that it's not reliable! – mchangun Jun 11 '14 at 06:44
  • Checkout `__iter__()` in ParameterGrid https://github.com/scikit-learn/scikit-learn/blob/0.14.X/sklearn/grid_search.py. Exactly what I want. – mchangun Jun 11 '14 at 06:46
  • 1
    You can zip `p` with `i` directly and save the time spent on repeatedly creating the list of keys. – user2357112 Jun 11 '14 at 07:00
  • Damn, the Python is just too powerful. I spent half an hour working out a recursive solution due to my lack of practice with the itertools. – timgeb Jun 11 '14 at 07:35