How can I write a python method to compute all combinations of a dict of lists?

Question:

I have an arbitrary python dictionary x such that the values of each key is itself a list. Here is an example:

x = {"first_name": ["Mahmoud", "Pei-chi"], "second_name": ["Abadi", "Yao"]}

Given x I would like write a method that computes a list of dictionaries such that each dictionary has the same keys as x but the values are each combination of individual list element. So in this case, the result should be:

[{"first_name": "Mahmoud", "second_name": "Abadi"}, 
 {"first_name": "Mahmoud", "second_name": "Yao"}, 
 {"first_name": "Pei-chi", "second_name": "Abadi"}, 
 {"first_name": "Pei-chi", "second_name": "Yao"}]

How can I do it? The dictionary x may have any arbitrary number of keys with arbitrary names.

Asked By: Saqib Ali

||

Answers:

You can issue the following list comprehension.

result = [dict(zip(x.keys(), t)) for t in product(*x.values())]
Answered By: timgeb

Python’s itertools.product() is good for this:

from itertools import product

x = {"first_name": ["Mahmoud", "Pei-chi"], "second_name": ["Abadi", "Yao"]}
dict_list = [{'first_name': f, 'second_name':s} for f, s in product(x['first_name'], x['second_name'])]

Giving you:

[{'first_name': 'Mahmoud', 'second_name': 'Abadi'}, {'first_name': 'Mahmoud', 'second_name': 'Yao'}, {'first_name': 'Pei-chi', 'second_name': 'Abadi'}, {'first_name': 'Pei-chi', 'second_name': 'Yao'}]
Answered By: Martin Evans

If you start from basic operations on list and dictionary with this simple for loops you can do above operations, but yeah it’s not as much optimized as of others in terms of neatness, nut complexity of operations is same.

    lis = []
    for f in x:
        if f =='first_name':
            for l in x[f]:
                for j in x['second_name']:
                    dic ={}
                    dic['first-name']=l;dic['last_name']=j
                    lis.append(dic)

O/P will be as we expect:

    [{'first-name': 'Mahmoud', 'last_name': 'Abadi'},
    {'first-name': 'Mahmoud', 'last_name': 'Yao'},
    {'first-name': 'Pei-chi', 'last_name': 'Abadi'},
    {'first-name': 'Pei-chi', 'last_name': 'Yao'}]
Answered By: Naitik Shukla

If your dict are unordered don’t worry you can use ordered dict , it will not change the result, it will give the same result every time.

dict_1 = {"first_name": ["Mahmoud", "Pei-chi"], "second_name": ["Abadi", "Yao"]}

import itertools
import collections
from operator import itemgetter
ordered_dict=collections.OrderedDict(sorted(dict_1.items(), key=itemgetter(0)))

items=[]
for key,value in ordered_dict.items():
    items.append(value)
    print([{"first_name":item[0],"last_name" :item[1]} for item in itertools.product(*items, repeat=1) if len(item)>1])

output:

[{'first_name': 'Mahmoud', 'last_name': 'Abadi'}, {'first_name': 'Mahmoud', 'last_name': 'Yao'}, {'first_name': 'Pei-chi', 'last_name': 'Abadi'}, {'first_name': 'Pei-chi', 'last_name': 'Yao'}]
Answered By: Aaditya Ura
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.