¿Cómo genero todas las permutaciones de una lista?

Resuelto Ricardo Reyes asked hace 15 años • 41 respuestas

¿Cómo genero todas las permutaciones de una lista? Por ejemplo:

permutations([])
[]

permutations([1])
[1]

permutations([1, 2])
[1, 2]
[2, 1]

permutations([1, 2, 3])
[1, 2, 3]
[1, 3, 2]
[2, 1, 3]
[2, 3, 1]
[3, 1, 2]
[3, 2, 1]
Ricardo Reyes avatar Sep 20 '08 01:09 Ricardo Reyes
Aceptado

Uso itertools.permutationsde la biblioteca estándar :

import itertools
list(itertools.permutations([1, 2, 3]))

Adaptado de aquí hay una demostración de cómo itertools.permutationspodría implementarse:

def permutations(elements):
    if len(elements) <= 1:
        yield elements
        return
    for perm in permutations(elements[1:]):
        for i in range(len(elements)):
            # nb elements[0:1] works in both string and list contexts
            yield perm[:i] + elements[0:1] + perm[i:]

En la documentación de itertools.permutations. Aquí hay uno:

def permutations(iterable, r=None):
    # permutations('ABCD', 2) --> AB AC AD BA BC BD CA CB CD DA DB DC
    # permutations(range(3)) --> 012 021 102 120 201 210
    pool = tuple(iterable)
    n = len(pool)
    r = n if r is None else r
    if r > n:
        return
    indices = range(n)
    cycles = range(n, n-r, -1)
    yield tuple(pool[i] for i in indices[:r])
    while n:
        for i in reversed(range(r)):
            cycles[i] -= 1
            if cycles[i] == 0:
                indices[i:] = indices[i+1:] + indices[i:i+1]
                cycles[i] = n - i
            else:
                j = cycles[i]
                indices[i], indices[-j] = indices[-j], indices[i]
                yield tuple(pool[i] for i in indices[:r])
                break
        else:
            return

Y otro, basado en itertools.product:

def permutations(iterable, r=None):
    pool = tuple(iterable)
    n = len(pool)
    r = n if r is None else r
    for indices in product(range(n), repeat=r):
        if len(set(indices)) == r:
            yield tuple(pool[i] for i in indices)
Eli Bendersky avatar Sep 19 '2008 18:09 Eli Bendersky

Para Python 2.6 en adelante:

import itertools
itertools.permutations([1, 2, 3])

Esto regresa como generador. Úselo list(permutations(xs))para regresar como una lista.

Brian avatar Sep 19 '2008 18:09 Brian

Primero, importe itertools:

import itertools

Permutación (el orden importa):

print(list(itertools.permutations([1,2,3,4], 2)))

[(1, 2), (1, 3), (1, 4),
(2, 1), (2, 3), (2, 4),
(3, 1), (3, 2), (3, 4),
(4, 1), (4, 2), (4, 3)]

Combinación (el orden NO importa):

print(list(itertools.combinations('123', 2)))

[('1', '2'), ('1', '3'), ('2', '3')]

Producto cartesiano (con varios iterables):

print(list(itertools.product([1,2,3], [4,5,6])))

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

Producto cartesiano (con un iterable y él mismo):

print(list(itertools.product([1,2], repeat=3)))

[(1, 1, 1), (1, 1, 2), (1, 2, 1), (1, 2, 2),
(2, 1, 1), (2, 1, 2), (2, 2, 1), (2, 2, 2)]
Bite code avatar Oct 04 '2008 12:10 Bite code