2

I have a list of lists containing unique strings and I want to produce an arbitrary number of different ways of sorting it. The list might look like the following:

list = [[a], [b,c], [d], [e,f,g]]

The order of the lists need to be the same but I want to shuffle the ordering within a list and then have them in a single list, e.g

list1 = [a,b,c,d,e,f,g]
list2 = [a,c,b,d,f,e,g]
...
...
listN = [a,c,b,d,f,g,e]

What is a good pythonic way of achieving this? I'm on python 2.7.

Chicony
  • 393
  • 3
  • 17
  • 1
    See [this question](http://stackoverflow.com/questions/104420/how-to-generate-all-permutations-of-a-list-in-python) – BVengerov Sep 28 '16 at 11:04
  • 1
    1. flat the list http://stackoverflow.com/questions/952914/making-a-flat-list-out-of-list-of-lists-in-python 2. generate permutations http://stackoverflow.com/questions/104420/how-to-generate-all-permutations-of-a-list-in-python – Querenker Sep 28 '16 at 11:06
  • 2
    To those answering: the OP does **not** want to flatten the input list. Its sub-lists are to be permuted independently, combinations of those permutations are generated, and then each output list is flattened. Note that each output list must contain all of the inner elements of the input list. – PM 2Ring Sep 28 '16 at 11:35

5 Answers5

3
from itertools import permutations, product

L = [['a'], ['b','c'], ['d'], ['e', 'f', 'g']]

for l in product(*map(lambda l: permutations(l), L)):
    print([item for s in l for item in s])

produces:

['a', 'b', 'c', 'd', 'e', 'f', 'g']
['a', 'b', 'c', 'd', 'e', 'g', 'f']
['a', 'b', 'c', 'd', 'f', 'e', 'g']
['a', 'b', 'c', 'd', 'f', 'g', 'e']
['a', 'b', 'c', 'd', 'g', 'e', 'f']
['a', 'b', 'c', 'd', 'g', 'f', 'e']
['a', 'c', 'b', 'd', 'e', 'f', 'g']
['a', 'c', 'b', 'd', 'e', 'g', 'f']
['a', 'c', 'b', 'd', 'f', 'e', 'g']
['a', 'c', 'b', 'd', 'f', 'g', 'e']
['a', 'c', 'b', 'd', 'g', 'e', 'f']
['a', 'c', 'b', 'd', 'g', 'f', 'e']
ewcz
  • 12,819
  • 1
  • 25
  • 47
3

You can do this by taking the Cartesian product of the permutations of the sub-lists, and then flattening the resulting nested tuples.

from itertools import permutations, product, chain

lst = [['a'], ['b', 'c'], ['d'], ['e', 'f', 'g']]

for t in product(*[permutations(u) for u in lst]):
    print([*chain.from_iterable(t)])

output

['a', 'b', 'c', 'd', 'e', 'f', 'g']
['a', 'b', 'c', 'd', 'e', 'g', 'f']
['a', 'b', 'c', 'd', 'f', 'e', 'g']
['a', 'b', 'c', 'd', 'f', 'g', 'e']
['a', 'b', 'c', 'd', 'g', 'e', 'f']
['a', 'b', 'c', 'd', 'g', 'f', 'e']
['a', 'c', 'b', 'd', 'e', 'f', 'g']
['a', 'c', 'b', 'd', 'e', 'g', 'f']
['a', 'c', 'b', 'd', 'f', 'e', 'g']
['a', 'c', 'b', 'd', 'f', 'g', 'e']
['a', 'c', 'b', 'd', 'g', 'e', 'f']
['a', 'c', 'b', 'd', 'g', 'f', 'e']

If you need to do this in Python 2, you can replace the print line with this:

print list(chain.from_iterable(t))

Here's a more compact version, inspired by ewcz's answer:

for t in product(*map(permutations, lst)):
    print list(chain.from_iterable(t))
PM 2Ring
  • 54,345
  • 6
  • 82
  • 182
0

This might not be the most elegant solution, but I think it does what you want

from itertools import permutations
import numpy as np

def fac(n):
    if n<=1:
        return 1
    else:
        return n * fac(n-1)

lists = [['a'], ['b','c'], ['d'], ['e','f','g']]

combined = [[]]
for perm in [permutations(l,r=len(l)) for l in lists]:
    expanded = []
    for e in list(perm):
        expanded += [list(l) + list(e) for l in combined]
    combined = expanded

## check length

print np.prod(map(fac,map(len,lists))), len(combined)

print '\n'.join(map(str,combined))
-1

You can flatten the list then simply generate its permutations:

from itertools import chain, permutations

li = [['a'], ['b','c'], ['d'], ['e','f','g']]
flattened = list(chain.from_iterable(li))
for perm in permutations(flattened, r=len(flattened)):
     print(perm)
>> ('a', 'b', 'c', 'd', 'e', 'f', 'g')
   ('a', 'b', 'c', 'd', 'e', 'g', 'f')
   ('a', 'b', 'c', 'd', 'f', 'e', 'g')
   ('a', 'b', 'c', 'd', 'f', 'g', 'e')
   ('a', 'b', 'c', 'd', 'g', 'e', 'f')
   ('a', 'b', 'c', 'd', 'g', 'f', 'e')
   ('a', 'b', 'c', 'e', 'd', 'f', 'g')
   ('a', 'b', 'c', 'e', 'd', 'g', 'f')
   ('a', 'b', 'c', 'e', 'f', 'd', 'g')
   ...
   ...
   ...
DeepSpace
  • 78,697
  • 11
  • 109
  • 154
-1
from itertools import chain, permutations

your_list = [[a], [b,c], [d], [e,f,g]]
flattened = chain.from_iterable(your_list)
perms = permutations(flattened)
for perm in perms:
    print perm

References:

怀春춘
  • 197
  • 5