I have got such a list of strings:
names = ['Katia', 'Alexandre']
and I want to achieve this result:
['Katia', 'Alexandre', 'Katia Alexandre', 'Alexandre Katia']
i.e. I need all the permutations of size range(1, length(names)+1).
I wrote this function that produces a list of iterables:
import itertools
def permutations_all_sizes(iterable):
sizes = range(1, len(iterable)+1)
permutations = [itertools.permutations(iterable, x) for x in sizes]
return permutations
Now, my idea was to execute a nested list comprehension to untuple the strings. However, wheter I do it nested or not nested the result is always the same:
perms = permutations_all_sizes(names)
[list(tup) for tup in perms]
[162]: [[('Catia',), ('Alexandre',)], [('Catia', 'Alexandre'), ('Alexandre', 'Catia')]]
[list(tup) for tup in [iterator for iterator in perms]]
[165]: [[('Catia',), ('Alexandre',)], [('Catia', 'Alexandre'), ('Alexandre', 'Catia')]]
Can somebody explain why such behaviour?
You can get the desired output with the following list comprehension:
print([' '.join(names) for tup in perms for names in tup])
Explanation of behavior of your code:
names = ['Katia', 'Alexandre']
, so
sizes = range(1, len(iterable)+1) = range(1, 3)
, so
permutations = [itertools.permutations(iterable, x) for x in sizes] =
= [itertools.permutations(iterable, 1), itertools.permutations(iterable, 2)
.
itertools.permutations(iterable, 1)
contains tuples of length 1 of elements of iterable:
names = ['Katia', 'Alexandre']
for something in itertools.permutations(names, 1):
print(something) # will print ('Katia',) then ('Alexandre',)
so doing list(tup)
of this permutation object will give a list of tuples like [('Catia',), ('Alexandre',)]
.
Same logic applies to itertools.permutations(iterable, 2)
:
names = ['Katia', 'Alexandre']
for something in itertools.permutations(names, 2):
print(something) # will print ('Katia', 'Alexandre'), then ('Alexandre', 'Katia')
and list(tup)
will give [('Katia', 'Alexandre'), ('Alexandre', 'Katia')]
Combining them in a list comprehension [list(tup) for tup in perms]
will give the output you get: [[('Catia',), ('Alexandre',)], [('Catia', 'Alexandre'), ('Alexandre', 'Catia')]]
Modifying list comprehension to [list(tup) for tup in [iterator for iterator in perms]]
does nothing: perms
is already a list and [iterator for iterator in perms]
is equivalent to perms
.