7

I'm trying to display all possible permutations of a list of numbers, for example if I have 334 I want to get:

3 3 4
3 4 3
4 3 3

I need to be able to do this for any set of digits up to about 12 digits long.

I'm sure its probably fairly simple using something like itertools.combinations but I can't quite get the syntax right.

TIA Sam

pylang
  • 40,867
  • 14
  • 129
  • 121
Sam Machin
  • 3,063
  • 5
  • 20
  • 18

4 Answers4

26
>>> lst = [3, 3, 4]
>>> import itertools
>>> set(itertools.permutations(lst))
{(3, 4, 3), (3, 3, 4), (4, 3, 3)}
SilentGhost
  • 307,395
  • 66
  • 306
  • 293
  • 1
    +1, distinct permutations of a list. `set(list())` to the rescue again. – Seth Jan 12 '10 at 22:43
  • @Seth Just use `itertools.combinations` instead. – nbro May 06 '19 at 22:31
  • @nbro - combinations and permutations are different operations (but related). In this case, `itertools.combinations([3, 3, 4], 3)` would just yield the original set, not the list of arrangements of the numbers in the set (i.e., the [permutations](https://en.wikipedia.org/wiki/Permutation)). – Seth May 08 '19 at 23:33
5

without itertools

def permute(LIST):
    length=len(LIST)
    if length <= 1:
        yield LIST
    else:
        for n in range(0,length):
             for end in permute( LIST[:n] + LIST[n+1:] ):
                 yield [ LIST[n] ] + end

for x in permute(["3","3","4"]):
    print x

output

$ ./python.py
['3', '3', '4']
['3', '4', '3']
['3', '3', '4']
['3', '4', '3']
['4', '3', '3']
['4', '3', '3']
ghostdog74
  • 327,991
  • 56
  • 259
  • 343
  • Was following this approach but could not understand what those two loops are actually doing. Would you find adding some text to the answer? – mad_ Jan 14 '19 at 15:08
3

You want permutations, not combinations. See: How to generate all permutations of a list in Python

>>> from itertools import permutations
>>> [a for a in permutations([3,3,4])]
[(3, 3, 4), (3, 4, 3), (3, 3, 4), (3, 4, 3), (4, 3, 3), (4, 3, 3)]

Note that it's permuting the two 3's (which is the correct thing mathematically to do), but isn't the same as your example. This will only make a difference if there are duplicated numbers in your list.

Community
  • 1
  • 1
Seth
  • 45,033
  • 10
  • 85
  • 120
1

I'd use python's itertools, but if you had to implement this yourself, here's code that returns all permutations of a specified size for a list of values.

Example: values = [1,2,3], size = 2 => [[3, 2], [2, 3], [2, 1], [3, 1], [1, 3], [1, 2]]

def permutate(values, size):
  return map(lambda p: [values[i] for i in p], permutate_positions(len(values), size))

def permutate_positions(n, size):
  if (n==1):
    return [[n]]

  unique = []
  for p in map(lambda perm: perm[:size], [ p[:i-1] + [n-1] + p[i-1:] for p in permutate_positions(n-1, size) for i in range(1, n+1) ]):
    if p not in unique:
      unique.append(p)

  return unique
Cat
  • 7,042
  • 8
  • 34
  • 36
  • 1
    This is a cool answer, I liked, but it could be good if values supports zero also. Ex: values = [0,1,2] this logic is failing. :) – Hara Mar 02 '17 at 12:52