0
votes

I am trying to generate a list of permutations in a loop and print for each iteration with output more than two (or write to lines of a file).

Example input list:

['one', 'two', 'three', 'four']

Required output:

['one', 'two', 'three', 'four']
['two', 'three', 'four']
['one', 'three', 'four']
['one', 'two', 'four']
['one', 'two']
['one', 'three']
['one', 'four']
['two', 'three']
['two', 'four']
['three', 'four']

This is what I've managed so far (very early in my Python life, please excuse):

from itertools import permutations

input = ['one', 'two', 'three', 'four']

def convertTuple(tup): 
    str =  ''.join(tup) 
    return str

while (len(input) > 1):    
    permlist = set(permutations(input))
    for i in permlist:
        print(i)
        i = convertTuple(i)
        outfile = open("out.txt", "w")
        outfile.write(i)
    input = input[:-1]
else:
    print("End of permutation cycle")

Which outputs:

('two', 'three', 'one', 'four')
('two', 'four', 'one', 'three')
('three', 'two', 'one', 'four')
('four', 'two', 'one', 'three')
('two', 'one', 'three', 'four')
('two', 'one', 'four', 'three')
('three', 'one', 'four', 'two')
('four', 'one', 'three', 'two')
('one', 'two', 'three', 'four')
('one', 'two', 'four', 'three')
('three', 'four', 'one', 'two')
('four', 'three', 'one', 'two')
('two', 'three', 'four', 'one')
('two', 'four', 'three', 'one')
('three', 'two', 'four', 'one')
('three', 'four', 'two', 'one')
('four', 'two', 'three', 'one')
('four', 'three', 'two', 'one')
('three', 'one', 'two', 'four')
('four', 'one', 'two', 'three')
('one', 'four', 'two', 'three')
('one', 'three', 'two', 'four')
('one', 'three', 'four', 'two')
('one', 'four', 'three', 'two')
('two', 'three', 'one')
('three', 'two', 'one')
('three', 'one', 'two')
('one', 'two', 'three')
('one', 'three', 'two')
('two', 'one', 'three')
('two', 'one')
('one', 'two')
End of permutation cycle

I understand I am going wrong with

input = input[:-1]

as it just removes the last value in the original list but I can't work out how to get only unique lists back with different numbers of values in each list...

Am I using the wrong part of itertools? Should I be using combinations or something else?

I am seriously stuck so any help is very much appreciated!

Thanks!

2

2 Answers

0
votes

I can't work out how to get only unique lists back with different numbers of values in each list... Should I be using combinations or something else?

Yes, use combinations to avoid getting the same set in a different order.

I understand I am going wrong with input = input[:-1]

Right; do not remove items from the candidate set yourself. The functionality you want is already built in.

>>> import itertools
>>> help(itertools.combinations)
Help on class combinations in module itertools:

class combinations(builtins.object)
 |  combinations(iterable, r) --> combinations object
 |
 |  Return successive r-length combinations of elements in the iterable.
 |
 |  combinations(range(4), 3) --> (0,1,2), (0,1,3), (0,2,3), (1,2,3)

All you need to do is provide the second parameter (it works for permutations too). Instead of repeatedly removing elements and finding combinations, just iterate over the possible values for output size.

(Incidentally, there is a slick example for this sort of thing in the "recipes" section of the documentation: the one labelled powerset. The power set of a set is basically the thing you're computing, except also including all the one-element results and the empty result.)

0
votes

Assuming ('one','two','three') was an accidental omit from your wanted list, this should do the trick:

from itertools import combinations

l = ['one', 'two', 'three', 'four']

for size in range(2,len(l)+1):
    for i in combinations(l,size):
        print(i)