2013-07-02 28 views
20

ecco la domanda:Generazione di tutte le combinazioni di una lista in pitone

Dato un elenco di elementi in Python, come potrei fare per ottenere tutte le possibili combinazioni delle macchine?

Ci sono diverse domande simili su questo sito, che suggeriamo di utilizzare itertools.combine, ma che restituisce solo un sottoinsieme di quello che mi serve:

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) 

Come si vede, restituisce solo gli elementi in un ordine rigoroso , non restituisce (2, 1), (3, 2), (3, 1), (2, 1, 3), (3, 1, 2), (2, 3, 1) e (3, 2) 1). C'è qualche soluzione alternativa? Non riesco a trovare nulla.

+0

l'ordine non importa in combinazioni, (2, 1) è uguale a (1, 2) –

+0

Buona domanda. Anche se tecnicamente potresti scrivere la tua funzione per ottenere queste combinazioni. – Sam

risposta

30

Usa 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) 
.... 

aiuto su 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 sarà ciò che desideri. Per definizione matematica, l'ordine non è rilevante per combinations, ovvero (1,2) è considerato identico a (2,1). Mentre con permutations, ogni ordinamento distinto conta come una permutazione univoca, quindi (1,2) e (2,1) sono completamente diversi.

6

Stai cercando itertools.permutations?

Da 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) 

codice di esempio:

>>> 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) 

Da Wikipedia, la differenza tra le permutazioni e combinazioni:

Permutazione:

informalmente una permutazione di un insieme di oggetti è una disposizione di quegli oggetti in un ordine particolare. Ad esempio, ci sono sei permutazioni dell'insieme {1,2,3}, vale a dire (1,2,3), (1,3,2), (2,1,3), (2,3,1) , (3,1,2) e (3,2,1).

Combinazione:

In matematica una combinazione è un modo di selezionare diverse cose su un gruppo più grande, dove (a differenza permutazioni) ordine non importa.

9

È possibile generare tutte le combinazioni di una lista in Python usando questo semplice codice

import itertools 

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

Risultato:

[(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

La domanda ha chiesto di vedere (2, 1) nei risultati. Dov'è il (2, 1) nella tua risposta? –

+2

La combinazione (2, 1) e (1, 2) entrambi sono la stessa persona. –

+1

Anche se la domanda contiene "combinazioni", ciò che si intende è permutazioni. Leggilo fino alla fine e vedi che entrambi (2, 1) e (1, 2) sono attesi da OP. –

0

presumo si desidera che tutte le possibili combinazioni come 'set' di valori.Ecco un pezzo di codice che ho scritto che potrebbe contribuire a dare un'idea:

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 

Ecco un esempio:

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

penso che questo ha n! complessità temporale, quindi fai attenzione. Questo funziona, ma non può essere più efficiente

2

Ecco una soluzione senza itertools

primo luogo permette di definire una traduzione tra un indicatore vettore di 0 e 1 s ed un elenco secondario (1 se l'articolo è in sottolista)

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

Avanti, ben definire una mappatura da un numero compreso tra 0 e 2^n-1 alla sua rappresentazione vettore binario (utilizzando la funzione di stringa format):

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

Tutto quello che abbiamo lasciato fare, è quello di iterare tutti i possibili numeri, e chiamare indicators2sublist

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

Ho pensato di mettere questo fuori là da quando ho potuto non bene ogni possibile risultato e tenendo a mente ho solo la più cruda di base di conoscenza quando si tratta di pitone e c'è probabilmente una soluzione molto più elegante ... (anche scusa i poveri nomi delle variabili

test = [1, 2, 3]

testing2 = [0]

n = -1

def testingSomethingElse (numero):

try: 

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

    n = -1 

    testing2[number] += 1 

except IndexError: 

    testing2.append(testing[0]) 

while 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] 

ho ottenuto via con == 4 perché sto lavorando con gli interi, ma potrebbe essere necessario modificare di conseguenza ...

Problemi correlati