2013-07-02 97 views
20

Hier ist die Frage:generieren alle Kombinationen von einer Liste in Python

eine Liste der Elemente in Python gegeben, wie würde ich gehen alle möglichen Kombinationen der Elemente zu bekommen?

Es gibt mehrere ähnliche Fragen auf dieser Seite, die itertools.combine empfehlen die Verwendung, aber das gibt nur einen Teil von dem, 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, es gibt nur Elemente in einer strengen Ordnung , nicht zurück (2, 1), (3, 2), (3, 1), (2, 1, 3), (3, 1, 2), (2, 3, 1) und (3, 2 , 1). Gibt es eine Workaround? Ich kann mir nichts einfallen lassen.

+0

Reihenfolge spielt keine Rolle in den Kombinationen, (2, 1) ist das gleiche wie (1, 2) –

+0

Gute Frage. Obwohl Sie technisch eine eigene Funktion schreiben könnten, um diese Kombinationen zu erhalten. – Sam

Antwort

30

Verwenden 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 auf 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) 
>>> 
2

itertools.permutations wird was Sie wollen. Nach mathematischer Definition spielt die Reihenfolge für combinations keine Rolle, was bedeutet, dass (1,2) als identisch mit (2,1) gilt. Während bei permutations jede eindeutige Reihenfolge als einmalige Permutation gilt, sind (1,2) und (2,1) völlig unterschiedlich.

6

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, der Unterschied zwischen Permutationen und Kombinationen:

Permutation:

Informell Eine Permutation einer Menge von Objekten ist 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 eine Kombination ist eine Möglichkeit, mehrere Dinge, die Auswahl aus einer größeren Gruppe, wo (im Gegensatz zu Permutationen) Reihenfolge keine Rolle spielt.

9

Sie alle Kombinationen aus einer Liste in Python diesen einfachen Code

import itertools 

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

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)] 
+0

Die Frage gestellt, um (2, 1) in den Ergebnissen zu sehen. Wo ist das (2, 1) in deiner Antwort? –

+2

Die Kombination (2, 1) und (1, 2) sind beide der gleiche Typ. –

+1

Obwohl die Frage "Kombinationen" enthält, sind Permutationen gemeint. Lies es bis zum Ende und sieh zu, dass sowohl (2, 1) als auch (1, 2) von OP erwartet werden. –

0

Ich nehme an, Sie alle möglichen Kombinationen als 'Sets' wollen von Werten.Hier ist ein Stück Code, den ich schrieb, dass helfen könnte Ihnen eine Idee:

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 n! Zeit Komplexität, also sei vorsichtig. Das funktioniert aber möglicherweise nicht die effizienteste

2

Hier ist eine Lösung ohne itertools

Zuerst lässt die Übersetzung zwischen einem Indikator Vektor 0 und 1 s definieren und eine Unterliste (1, wenn das Element in der Unterliste ist)

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

nächste definiert Well eine Zuordnung von einer Zahl zwischen 0 und 2^n-1 zur seiner binären Vektordarstellung (string des format Funktion):

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

Alles, was wir tun müssen, nach links, ist es, alle möglichen Zahlen iterieren, und rufen indicators2sublist

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

nur dachte ich, das da draußen setzen würde, da konnte ich nicht in Ordnung jeder möglichen Ergebnis und ich habe nur die rawest grundlegendsten Kenntnisse im Auge behalten, wenn es um python kommt, und es ist wahrscheinlich eine viel elegantere Lösung ... (auch die schlechten Variablennamen

Prüfung entschuldigen = [1, 2, 3]

testing2 = [0]

n = -1

def testingSomethingElse (Anzahl):

try: 

    testing2[0:len(testing2)] == testing[0] 

    n = -1 

    testing2[number] += 1 

except IndexError: 

    testing2.append(testing[0]) 

während True:

n += 1 

testing2[0] = testing[n] 

print(testing2) 

if testing2[0] == testing[-1]: 

    try: 

     n = -1 

     testing2[1] += 1 

    except IndexError: 

     testing2.append(testing[0]) 

    for i in range(len(testing2)): 

     if testing2[i] == 4: 

      testingSomethingElse(i+1) 

      testing2[i] = testing[0] 

i mit == entwischt 4, weil ich mit ganzen Zahlen arbeiten bin aber Sie müssen dies möglicherweise entsprechend ändern ...

Verwandte Themen