DrDom
DrDom

Reputation: 4133

Generate combinations (in specific order) of all permutations of the dict of lists

I have a dict of lists

d = {'A': [1,2,3], 'B': [4,5], 'C': [6]}

I need to produce all permutation of each list (A, B and C). This is OK.

p = {}
for k in d.keys():
    p[k] = [i for i in itertools.permutations(d[k])]

This results in p

{'A': [(1, 2, 3), (1, 3, 2), (2, 1, 3), (2, 3, 1), (3, 1, 2), (3, 2, 1)],
 'B': [(4, 5), (5, 4)],
 'C': [(6,)]}

Then I need to merge tuples from A, B and C lists but in the specific order (for example in order of sorted(p.keys()) which actually gives ['A', 'B', 'C']). So I should obtain list of tuples of integers:

[(1,2,3,4,5,6),
 (1,2,3,5,4,6),
 (1,3,2,4,5,6),
 (1,3,2,5,4,6),
 ...
 (3,2,1,5,4,6)
]

I know that itertools.product could be used in such cases, but the initial dictionary d can consist of arbitrary number of values with different keys and I don't know how to use it in this case. Or maybe you will be able to suggest totally different solution of the desribed problem. The faster the final solution will work the better.

Upvotes: 2

Views: 1316

Answers (1)

Jon Clements
Jon Clements

Reputation: 142236

Something like this:

from itertools import permutations, product, chain

d = {'A': [1,2,3], 'B': [4,5], 'C': [6]}
# You don't need to materialise permutations here, but this matches your existing dict
p = {k:list(permutations(v)) for k, v in d.iteritems()}    

for blah in product(*map(p.get, sorted(p))):
    print list(chain.from_iterable(blah)) # or use tuple instead of list

[1, 2, 3, 4, 5, 6]
[1, 2, 3, 5, 4, 6]
[1, 3, 2, 4, 5, 6]
[1, 3, 2, 5, 4, 6]
[2, 1, 3, 4, 5, 6]
[2, 1, 3, 5, 4, 6]
[2, 3, 1, 4, 5, 6]
[2, 3, 1, 5, 4, 6]
[3, 1, 2, 4, 5, 6]
[3, 1, 2, 5, 4, 6]
[3, 2, 1, 4, 5, 6]
[3, 2, 1, 5, 4, 6]

Upvotes: 5

Related Questions