Tengo una lista con 15 números y necesito escribir un código que produzca las 32,768 combinaciones de esos números.
Encontré un código (buscando en Google) que aparentemente hace lo que estoy buscando, pero encontré el código bastante opaco y desconfío de usarlo. Además, tengo la sensación de que debe haber una solución más elegante.
Lo único que se me ocurre sería recorrer los enteros decimales 1–32768 y convertirlos en binarios, y usar la representación binaria como filtro para seleccionar los números apropiados.
¿Alguien sabe de una mejor manera? ¿Usando map()
, tal vez?
python
combinations
Ben
fuente
fuente
product
, etc.)Respuestas:
Echa un vistazo a itertools.combinations :
¡Desde 2.6, las baterías están incluidas!
fuente
list(itertools.combinations(iterable, r))
r
, es decir, combinaciones de subsecuencias de elementos de cualquier longitud?Esta respuesta perdió un aspecto: el OP solicitó TODAS las combinaciones ... no solo combinaciones de longitud "r".
Así que tendrías que recorrer todas las longitudes "L":
O bien, si desea ponerse elegante (o doblar el cerebro de quien lea su código después de usted), puede generar la cadena de generadores de "combinaciones ()" e iterar a través de eso:
fuente
powerset()
función de generador en la sección de recetas de laitertools
documentación es más simple, potencialmente usa menos memoria y es probable que sea más rápida que la implementación que se muestra aquí.itertools.combinations
conserva el orden del artículo en las listas que produce. Por lo tanto, si la entrada está ordenada léxicamente, entonces cada una de las salidas también lo estará.itertools.combinations
genera las combinaciones de k entre n en orden lexicográfico, pero no todas las combinaciones hasta k entre n.powerset
genera todas las combinaciones hasta k, pero no en orden lexicográfico por lo que yo entiendo: powerset ([1,2]) -> [(), (1,), (2,), (1, 2)] . ¿No debería ser: [(), (1,), (1, 2), (2,)]?Aquí hay una línea perezosa, que también usa itertools:
Idea principal detrás de esta respuesta: hay 2 ^ N combinaciones, lo mismo que el número de cadenas binarias de longitud N. Para cada cadena binaria, elige todos los elementos correspondientes a un "1".
Cosas para considerar:
len(...)
enitems
(solución: siitems
es algo así como un iterable como un generador, lo convierten en una lista primero conitems=list(_itemsArg)
)items
no sea aleatorio (solución alternativa: no se vuelva loco){2,2,1}
y{2,1,1}
se colapso tanto a{2,1}
(solución: el usocollections.Counter
como una gota en el reemplazo paraset
, es básicamente un conjunto múltiple ... aunque puede que necesite su uso posteriortuple(sorted(Counter(...).elements()))
, si lo necesita para ser hashable)Manifestación
fuente
En los comentarios bajo la respuesta altamente votada por @Dan H, se menciona la
powerset()
receta en laitertools
documentación, incluida una del propio Dan . Sin embargo , hasta ahora nadie lo ha publicado como respuesta. Dado que es probablemente uno de los mejores, si no el mejor, del problema, y dado un poco de aliento de otro comentarista, se muestra a continuación. La función produce todas las combinaciones únicas de los elementos de la lista de todas las longitudes posibles (incluidas las que contienen cero y todos los elementos).Nota : Si el, sutilmente diferente, meta es obtener sólo las combinaciones de elementos únicos, cambie la línea
s = list(iterable)
des = list(set(iterable))
eliminar todo elemento duplicadas. En cualquier caso, el hecho de queiterable
finalmente se convierta en unlist
medio funcionará con generadores (a diferencia de varias de las otras respuestas).Salida:
fuente
list()
conversión en primer lugar?Aquí hay uno que usa recursión:
fuente
new_data = copy.copy(data)
- Esta fila es redundante por lo que veo, no influye en nadaEsta línea le brinda todas las combinaciones (entre
0
yn
elementos si la lista / conjunto original contienen
elementos distintos) y utiliza el método nativoitertools.combinations
:Python 2
Python 3
El resultado será:
Pruébalo en línea:
http://ideone.com/COghfX
fuente
['b', 'a']
.TypeError: can only concatenate list (not "map") to list
Estoy de acuerdo con Dan H en que Ben realmente pidió todas las combinaciones.
itertools.combinations()
No da todas las combinaciones.Otro problema es que, si la entrada iterable es grande, quizás sea mejor devolver un generador en lugar de todo en una lista:
fuente
Este es un enfoque que puede transferirse fácilmente a todos los lenguajes de programación que admitan la recursión (sin itertools, sin rendimiento, sin comprensión de lista) :
fuente
Puede generar todas las combinaciones de una lista en Python usando este código simple
El resultado sería:
fuente
Pensé que agregaría esta función para aquellos que buscan una respuesta sin importar itertools o cualquier otra biblioteca adicional.
Uso simple del generador de rendimiento:
Salida del ejemplo de uso anterior:
fuente
Aquí hay otra solución (una línea), que implica el uso de la
itertools.combinations
función, pero aquí usamos una comprensión de lista doble (en oposición a un bucle for o sum):Manifestación:
fuente
salida
fuente
A continuación se muestra una "respuesta recursiva estándar", similar a la otra respuesta similar https://stackoverflow.com/a/23743696/711085 . (Realmente no tenemos que preocuparnos por quedarnos sin espacio en la pila ya que no hay forma de que podamos procesar todas las permutaciones de N!).
Visita cada elemento por turno, y lo toma o lo deja (podemos ver directamente la cardinalidad 2 ^ N de este algoritmo).
Manifestación:
fuente
Usando la comprensión de la lista:
La salida sería:
fuente
Este código emplea un algoritmo simple con listas anidadas ...
fuente
""
).Sé que es mucho más práctico usar itertools para obtener todas las combinaciones, pero puede lograr esto en parte con solo la comprensión de la lista si así lo desea, siempre que desee codificar mucho
Para combinaciones de dos pares:
Y, para combinaciones de tres pares, es tan fácil como esto:
El resultado es idéntico al uso de itertools.combinations:
fuente
Sin usar itertools:
fuente
Aquí hay dos implementaciones de
itertools.combinations
Uno que devuelve una lista
Uno devuelve un generador
Tenga en cuenta que se recomienda proporcionar una función auxiliar a aquellos porque el argumento de anteponer es estático y no cambia con cada llamada
Este es un caso muy superficial, pero es mejor prevenir que curar
fuente
Qué tal esto ... usó una cadena en lugar de una lista, pero lo mismo ... la cadena se puede tratar como una lista en Python:
fuente
Combinación de itertools
Gracias
fuente
Sin
itertools
Python 3 podrías hacer algo como esto:donde inicialmente
carry = "".
fuente
3 funciones:
fuente
Esta es mi implementación
fuente
También puede usar la función powerset del excelente
more_itertools
paquete.También podemos verificar que cumple con los requisitos de OP
fuente
fuente
Si alguien está buscando una lista inversa, como yo estaba:
fuente
fuente