it-swarm.com.de

Generierung aller Kombinationen einer Liste in Python

Hier ist die Frage:

Wie würde ich bei einer Liste von Elementen in Python vorgehen, um alle möglichen Kombinationen der Elemente zu erhalten?

Es gibt mehrere ähnliche Fragen auf dieser Website, die die Verwendung von itertools.combine vorschlagen, aber nur eine Teilmenge dessen zurückgibt, was ich brauche:

stuff = [1, 2, 3]
for L in range(0, len(stuff)+1):
    for subset in itertools.combinations(stuff, L):
        print(subset)

()
(1,)
(2,)
(3,)
(1, 2)
(1, 3)
(2, 3)
(1, 2, 3)

Wie Sie sehen, werden nur Artikel in einer strengen Reihenfolge zurückgegeben, nicht jedoch (2, 1), (3, 2), (3, 1), (2, 1, 3), (3, 1, 2), ( 2, 3, 1) und (3, 2, 1). Gibt es eine Problemumgehung? Ich kann mir anscheinend nichts einfallen lassen.

22
Minas Abovyan

Verwenden Sie itertools.permutations:

>>> import itertools
>>> stuff = [1, 2, 3]
>>> for L in range(0, len(stuff)+1):
        for subset in itertools.permutations(stuff, L):
                print(subset)
...         
()
(1,)
(2,)
(3,)
(1, 2)
(1, 3)
(2, 1)
(2, 3)
(3, 1)
....

hilfe zu itertools.permutations:

permutations(iterable[, r]) --> permutations object

Return successive r-length permutations of elements in the iterable.

permutations(range(3), 2) --> (0,1), (0,2), (1,0), (1,2), (2,0), (2,1)
>>> 
33

Mit diesem einfachen Code können Sie alle Kombinationen einer Liste in Python erzeugen.  

import itertools

a = [1,2,3,4]
for i in xrange(1,len(a)+1):
   print list(itertools.combinations(a,i))

Ergebnis:

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

Suchen Sie stattdessen nach itertools.permutations

Von help(itertools.permutations),

Help on class permutations in module itertools:

class permutations(__builtin__.object)
 |  permutations(iterable[, r]) --> permutations object
 |  
 |  Return successive r-length permutations of elements in the iterable.
 |  
 |  permutations(range(3), 2) --> (0,1), (0,2), (1,0), (1,2), (2,0), (2,1)

Beispielcode :

>>> from itertools import permutations
>>> stuff = [1, 2, 3]
>>> for i in range(0, len(stuff)+1):
        for subset in permutations(stuff, i):
               print(subset)


()
(1,)
(2,)
(3,)
(1, 2)
(1, 3)
(2, 1)
(2, 3)
(3, 1)
(3, 2)
(1, 2, 3)
(1, 3, 2)
(2, 1, 3)
(2, 3, 1)
(3, 1, 2)
(3, 2, 1)

Aus Wikipedia besteht der Unterschied zwischen Permutationen und Kombinationen: 

Permutation:

Informell ist eine Permutation einer Menge von Objekten eine Anordnung dieser Objekte in einer bestimmten Reihenfolge. Zum Beispiel gibt es sechs Permutationen der Menge {1,2,3}, nämlich (1,2,3), (1,3,2), (2,1,3), (2,3,1) (3,1,2) und (3,2,1).

Kombination: 

In der Mathematik ist eine Kombination eine Möglichkeit, mehrere Dinge aus einer größeren Gruppe auszuwählen, wobei (anders als bei Permutationen) die Reihenfolge keine Rolle spielt.

6
Sukrit Kalra

Hier ist eine Lösung ohne itertools

Zuerst definieren wir eine Übersetzung zwischen einem Indikatorvektor von 0 und 1s und einer Unterliste (1, wenn sich das Element in der Unterliste befindet).

def indicators2sublist(indicators,arr):
   return [item for item,indicator in Zip(arr,indicators) if int(indicator)==1]

Als Nächstes definieren Sie ein Mapping von einer Zahl zwischen 0 und 2^n-1 bis zur binären Vektordarstellung (mit der Funktion format der Zeichenfolge):

def bin(n,sz):
   return ('{d:0'+str(sz)+'b}').format(d=n)

Alles, was wir noch tun müssen, ist, alle möglichen Zahlen zu durchlaufen und indicators2sublist anzurufen.

def all_sublists(arr):
  sz=len(arr)
  for n in xrange(0,2**sz):
     b=bin(n,sz)
     yield indicators2sublist(b,arr)
2
Uri Goren

itertools.permutations wird das sein, was du willst. Nach der mathematischen Definition spielt die Reihenfolge für combinations keine Rolle. Die Bedeutung von (1,2) gilt als identisch mit (2,1). Während bei permutations jede unterschiedliche Reihenfolge als eindeutige Permutation gilt, sind (1,2) und (2,1) völlig verschieden.

2
Brien

Ich gehe davon aus, dass Sie alle möglichen Kombinationen als 'Mengen' von Werten wünschen. Hier ist ein Stück Code, den ich geschrieben habe, der Ihnen eine Idee geben könnte:

def getAllCombinations(object_list):
    uniq_objs = set(object_list)
    combinations = []
    for obj in uniq_objs:
        for i in range(0,len(combinations)):
            combinations.append(combinations[i].union([obj]))
        combinations.append(set([obj]))
return combinations

Hier ist ein Beispiel:

combinations = getAllCombinations([20,10,30])
combinations.sort(key = lambda s: len(s))
print combinations
... [set([10]), set([20]), set([30]), set([10, 20]), set([10, 30]), set([20, 30]), set([10, 20, 30])]

Ich denke das hat n! Zeit Komplexität, also seien Sie vorsichtig. Dies funktioniert, ist aber möglicherweise nicht besonders effizient

0
Shashank Singh