0

I have something like this:

{'event1': [2000, 3000, 4000], 'event2': [123, 456]}

but with N keys, not only two like the example

I need to get something like this:

[
{'event1': 2000, 'event2': 123},
{'event1': 2000, 'event2': 456},
{'event1': 3000, 'event2': 123},
{'event1': 3000, 'event2': 456},
{'event1': 4000, 'event2': 123},
{'event1': 4000, 'event2': 456}
]

As you see, the order does not matter and the size of the list is variable for each key. How would you approach this problem?

I tried to decouple values from keys and iterate between the various lists but after that, I can't couple again the single values with their previous keys.

0

4 Answers 4

1

You can use itertools.product, but the data will need some massaging to make it generally applicable to multiple keys.

from itertools import product

data = {
    'event1': [2000, 3000, 4000],
    'event2': [123, 456],
    'event3': [771, 9]
}

# get the keys to ensure
keys = sorted(data)
[
    dict(zip(keys, tup)) 
    for tup in product(*[data[k] for k in keys])
]

This returns:

[{'event1': 2000, 'event2': 123, 'event3': 771},
 {'event1': 2000, 'event2': 123, 'event3': 9},
 {'event1': 2000, 'event2': 456, 'event3': 771},
 {'event1': 2000, 'event2': 456, 'event3': 9},
 {'event1': 3000, 'event2': 123, 'event3': 771},
 {'event1': 3000, 'event2': 123, 'event3': 9},
 {'event1': 3000, 'event2': 456, 'event3': 771},
 {'event1': 3000, 'event2': 456, 'event3': 9},
 {'event1': 4000, 'event2': 123, 'event3': 771},
 {'event1': 4000, 'event2': 123, 'event3': 9},
 {'event1': 4000, 'event2': 456, 'event3': 771},
 {'event1': 4000, 'event2': 456, 'event3': 9}]
1
import itertools

original_dict = {'event1': [2000, 3000, 4000], 'event2': [123, 456],  'event3': [0, 1]}

keys = original_dict.keys()
values = original_dict.values()

combinations = list(itertools.product(*values))

result = [dict(zip(keys, combination)) for combination in combinations]
{'event1': 2000, 'event2': 123, 'event3': 0}
{'event1': 2000, 'event2': 123, 'event3': 1}
{'event1': 2000, 'event2': 456, 'event3': 0}
{'event1': 2000, 'event2': 456, 'event3': 1}
{'event1': 3000, 'event2': 123, 'event3': 0}
{'event1': 3000, 'event2': 123, 'event3': 1}
{'event1': 3000, 'event2': 456, 'event3': 0}
{'event1': 3000, 'event2': 456, 'event3': 1}
{'event1': 4000, 'event2': 123, 'event3': 0}
{'event1': 4000, 'event2': 123, 'event3': 1}
{'event1': 4000, 'event2': 456, 'event3': 0}
{'event1': 4000, 'event2': 456, 'event3': 1}

This should work for original_dict of any length

4
  • 1
    Same answer as mine, but yours is cleaner.
    – James
    Commented Jul 9 at 14:46
  • Does [dict(zip(keys, combination)) for combination in combinations] works only because in latest Python dictionaries are ordered, right?
    – Lomiz
    Commented Jul 9 at 15:29
  • @Lomiz what do you mean? If they aren't ordered, what should be broken in your opinion in that case? Commented Jul 9 at 15:44
  • Sorry, stupid question, now I got how it worked!
    – Lomiz
    Commented Jul 10 at 15:58
1

This looks like a cartesian product

Easiest way to do this operation is by using itertools.product from the standard library:

import itertools as it

original_dict = {'event1': [2000, 3000, 4000], 'event2': [123, 456]}

keys = original_dict.keys()

result = []

for values in it.product(*(original_dict[key] for key in keys)):
   result.append({key: value for key, value in zip(keys, values)})

print(result)

output:

[{'event1': 2000, 'event2': 123},
 {'event1': 2000, 'event2': 456},
 {'event1': 3000, 'event2': 123},
 {'event1': 3000, 'event2': 456},
 {'event1': 4000, 'event2': 123},
 {'event1': 4000, 'event2': 456}]
1
  • 1
    oh true, I misread, I'll edit that
    – tbrugere
    Commented Jul 9 at 14:45
0
from itertools import product

original_dict = {'event1': [2000, 3000, 4000], 'event2': [123, 456]}


[dict(zip(original_dict.keys(), values)) for values in product(*original_dict.values()]

Not the answer you're looking for? Browse other questions tagged or ask your own question.