hawk_
hawk_

Reputation: 15

mapping list of numbers to dictionary keys with multiple values

I will start with an example. let's say I have a dictionary such as:

d = {1:['A','B'],
     2:['C']}

and a list:

vals = [1,2]

I want to map these values in the list (vals) to all possible ones in the dictionary (d). so the output here should be two lists such as:

[[ 'A','C']['B','C']]

this is basically the problem I am facing now. I thought I can do it with for loop but when we faced this dictionary and list of values,I couldn't do it using a for loop or even a nested loops:

d = {1:['A','B','C'] ,
     2:['D','E'],
     3:['F','G'],
     4:['I'] }

values = [1,2,3,4]

the output here should be:

[['A', 'D', 'F', 'I'], 
 ['A', 'D', 'G', 'I'],
 ['A', 'E', 'F', 'I'], 
 ['A', 'E', 'G', 'I'],
 ['B', 'D', 'F', 'I'], 
 ['B', 'D', 'G', 'I'],
 ['B', 'E', 'F', 'I'],
 ['B', 'E', 'G', 'I'], 
 ['C', 'D', 'F', 'I'],
 ['C', 'D', 'G', 'I'],
 ['C', 'E', 'F', 'I'],
 ['C', 'E', 'G', 'I']]

Upvotes: 0

Views: 47

Answers (2)

Daweo
Daweo

Reputation: 36630

If you simple need working solution, use that of Mark Meyer, however if you are curious if it is doable via fors, answer is yes, following way:

d = {1:['A','B','C'] ,2:['D','E'],3:['F','G'],4:['I']}
for k in sorted(d.keys())[:-1][::-1]:
    d[k] = [(i+j) for i in d[k] for j in d[k+1]]
out = [tuple(i) for i in d[1]]
print(out)

gives:

[('A', 'D', 'F', 'I'), ('A', 'D', 'G', 'I'), ('A', 'E', 'F', 'I'), ('A', 'E', 'G', 'I'), ('B', 'D', 'F', 'I'), ('B', 'D', 'G', 'I'), ('B', 'E', 'F', 'I'), ('B', 'E', 'G', 'I'), ('C', 'D', 'F', 'I'), ('C', 'D', 'G', 'I'), ('C', 'E', 'F', 'I'), ('C', 'E', 'G', 'I')]

Note that this solution assumes that dict d is correct, i.e. its keys are subsequent numbers starting at 1 and all values are lists of one-letter strs. Now explanation: outer for is working on numbers from second greatest to 1, descending, in this particular case: 3,2,1. List comprehension is making "every-with-every" join (like SQL CROSS JOIN) of k-th list with (k+1)-th list and is effect is stored under current key k. Finally I retrieve d[1] which is list of strs and convert it to list of tuples compliant with requirements. If how this solution is working explanation is unclear for you please copy code snippet, add print(d) below d[k] = ... and observe what it prints.

Upvotes: 0

Mark
Mark

Reputation: 92460

You can use itertools product() for this. Just make a comprehension of the indexes you want to include and pass them to product(). If you are okay with tuples it's a nice one-liner:

import itertools

list(itertools.product(*(d[x] for x in values)))

results:

[('A', 'D', 'F', 'I'),
 ('A', 'D', 'G', 'I'),
 ('A', 'E', 'F', 'I'),
 ('A', 'E', 'G', 'I'),
 ('B', 'D', 'F', 'I'),
 ('B', 'D', 'G', 'I'),
 ('B', 'E', 'F', 'I'),
 ('B', 'E', 'G', 'I'),
 ('C', 'D', 'F', 'I'),
 ('C', 'D', 'G', 'I'),
 ('C', 'E', 'F', 'I'),
 ('C', 'E', 'G', 'I')]

Upvotes: 2

Related Questions