Kunal Sharma
Kunal Sharma

Reputation: 107

Need to create a dictionary from multiple values

I am trying to create a dictionary using below code:

def func(inp):
    return (dict(zip(inp.keys(), values)) for values in product(*inp.values()))
    
x ={'Key1': ['111', '42343'], 'key2': ['TEST', 'TESTTT123'], 'Key3': ['Cell Phone', 'e-Mail'], 'Key5': ['32142341', '[email protected]']}
   
func(x)

But It gave me a cartesian product

{'Key1': '111', 'Key2': 'TEST', 'Key3': 'Cell Phone', 'Key4': '32142341'}
{'Key1': '111', 'Key2': 'TEST', 'Key3': 'Cell Phone', 'Key4': '[email protected]'}
{'Key1': '111', 'Key2': 'TEST', 'Key3': 'e-Mail', 'Key4': '32142341'}
{'Key1': '111', 'Key2': 'TEST', 'Key3': 'e-Mail', 'Key4': '[email protected]'}
{'Key1': '111', 'Key2': 'TESTTT123', 'Key3': 'Cell Phone', 'Key4': '32142341'}
{'Key1': '111', 'Key2': 'TESTTT123', 'Key3': 'Cell Phone', 'Key4': '[email protected]'}
{'Key1': '111', 'Key2': 'TESTTT123', 'Key3': 'e-Mail', 'Key4': '32142341'}
{'Key1': '111', 'Key2': 'TESTTT123', 'Key3': 'e-Mail', 'Key4': '[email protected]'}
{'Key1': '42343', 'Key2': 'TEST', 'Key3': 'Cell Phone', 'Key4': '32142341'}
{'Key1': '42343', 'Key2': 'TEST', 'Key3': 'Cell Phone', 'Key4': '[email protected]'}
{'Key1': '42343', 'Key2': 'TEST', 'Key3': 'e-Mail', 'Key4': '32142341'}
{'Key1': '42343', 'Key2': 'TEST', 'Key3': 'e-Mail', 'Key4': '[email protected]'}
{'Key1': '42343', 'Key2': 'TESTTT123', 'Key3': 'Cell Phone', 'Key4': '32142341'}
{'Key1': '42343', 'Key2': 'TESTTT123', 'Key3': 'Cell Phone', 'Key4': '[email protected]'}
{'Key1': '42343', 'Key2': 'TESTTT123', 'Key3': 'e-Mail', 'Key4': '32142341'}
{'Key1': '42343', 'Key2': 'TESTTT123', 'Key3': 'e-Mail', 'Key4': '[email protected]'}

However output req is:

{'Key1': '111', 'Key2': 'TEST', 'Key3': 'Cell Phone', 'Key4': '32142341'}
{'Key1': '42343', 'Key2': 'TESTTT123', 'Key3': 'e-Mail', 'Key4': '[email protected]'}

any help how to avoid cartesian product?

Upvotes: 1

Views: 43

Answers (2)

blhsing
blhsing

Reputation: 106598

Your solution is pretty close but unnecessarily calls the cartesian product function. You can instead zip directly the values of the input dict so that you can iterate through them to create sub-dicts by zipping them with the keys of the input dict:

def func(inp):
    return (dict(zip(inp, values)) for values in zip(*inp.values()))

Upvotes: 1

costaparas
costaparas

Reputation: 5237

Just loop through the length of the lists using range and use a dictionary comprehension to construct the individual dicts, selecting the ith element of the list each time:

def func(inp):
    return ({k: v[i] for k, v in inp.items()} for i in range(len(list(inp.values())[0])))
    
x = {'Key1': ['111', '42343'], 'key2': ['TEST', 'TESTTT123'], 'Key3': ['Cell Phone', 'e-Mail'], 'Key4': ['32142341', '[email protected]']}
   
res = func(x)

for r in res:
    print(r)

Output:

{'Key1': '111', 'Key2': 'TEST', 'Key3': 'Cell Phone', 'Key4': '32142341'}
{'Key1': '42343', 'Key2': 'TESTTT123', 'Key3': 'e-Mail', 'Key4': '[email protected]'}

This uses the length of the list of the first key/value pair, and assumes all the lists are of the equal length.

Upvotes: 1

Related Questions