2010-01-30 15 views
5

ho una lista L = [a, b, c] e voglio generare una lista di tuple:Lista moltiplicazione

[(a,a), (a,b), (a,c), (b,a), (b,b), (b,c)...] 

Ho provato a fare L * L, ma non ha funzionato. Qualcuno può dirmi come ottenerlo in Python.

+0

Questo tipo di "prodotto" è anche chiamato "prodotto cartesiano" o "prodotto diretto" (non sono sicuro che un termine o l'altro sia più appropriato qui, ma il documento stesso Python utilizza "prodotto cartesiano"). – MatrixFrog

risposta

13

Il modulo itertools contiene una serie di funzioni utili per questo genere di cose. Sembra che si può essere alla ricerca di product:

>>> import itertools 
>>> L = [1,2,3] 
>>> itertools.product(L,L) 
<itertools.product object at 0x83788> 
>>> list(_) 
[(1, 1), (1, 2), (1, 3), (2, 1), (2, 2), (2, 3), (3, 1), (3, 2), (3, 3)] 
7

Dai uno sguardo al modulo itertools, che fornisce un membro product.

L =[1,2,3] 

import itertools 
res = list(itertools.product(L,L)) 
print(res) 

Dà:

[(1,1),(1,2),(1,3),(2,1), .... and so on] 
22

Puoi farlo con una lista di comprensione:

[ (x,y) for x in L for y in L] 

modificare

È inoltre possibile utilizzare itertools.product come altri hanno suggerito, ma solo se si utilizza 2.6 in poi. La comprensione delle liste funzionerà con tutte le versioni di Python 2.0. Se usi itertools.product ricordati che restituisce un generatore invece di una lista, quindi potresti aver bisogno di convertirlo (a seconda di cosa vuoi fare con esso).

+0

Grazie per il chiarimento. – Schitti

0

x = [a, b, c] y = [] per elemento in x: per item2 in x: y.append ((voce, item2))

Forse non il modo Pythonic ma lavorando

0

Ok provato:

L2 = [(x, y) per x in L per x in L] e questo ottenuto L quadrato.

È questo il modo migliore per fare questo? Mi aspetto che L * L funzioni in python.

+0

Aspettative sbagliate - 'sequenza * sequenza' è ** non ** definita (solo' sequence * int', che fa qualcosa ** very ** different! -). –

+0

Oops, ho scritto questo prima di vedere le risposte. Ignora – Schitti

3

due alternative principali:

>>> L = ['a', 'b', 'c'] 
>>> import itertools 
>>> list(itertools.product(L, L)) 
[('a', 'a'), ('a', 'b'), ('a', 'c'), ('b', 'a'), ('b', 'b'), ('b', 'c'), ('c', 'a'), ('c', 'b'), ('c', 'c')] 
>>> [(one, two) for one in L for two in L] 
[('a', 'a'), ('a', 'b'), ('a', 'c'), ('b', 'a'), ('b', 'b'), ('b', 'c'), ('c', 'a'), ('c', 'b'), ('c', 'c')] 
>>> 

l'ex uno ha bisogno di Python 2.6 o superiore - queste ultime opere in quasi ogni versione di Python si potrebbe essere legato a.

+0

L'uso di itertools mi sembra strano se vuoi solo convertire direttamente in un elenco.La comprensione delle liste è probabilmente più efficiente, altrettanto leggibile e probabilmente più manutenibile in quanto vi sono delle modifiche che è possibile eseguire direttamente nell'espressione. Più astrazione può significare più inflessibilità, e il punto è nascondere i dettagli che * speri * (ma non puoi essere sicuro) di cui non dovrai più preoccuparti. – Steve314

0

La più vecchia maniera per farlo sarebbe:

def perm(L): 
    result = [] 
    for i in L: 
     for j in L: 
      result.append((i,j)) 
    return result 

Questo ha un tempo di esecuzione di O (n^2) ed è quindi piuttosto lento, ma si potrebbe prendere in considerazione che sia lo stile "vintage" codice.

+0

Tutti gli approcci a questo hanno il runtime O (n^2) nel migliore dei casi, la ragione per cui tutti devono generare tuple O (n^2). L'uso di un iteratore come itertools ti consente di posticipare parte di quel lavoro, ma non puoi evitarlo completamente. Il tuo approccio potrebbe essere anche O (n^3) - l'aggiunta alle liste potrebbe essere O (n) piuttosto che O (1) a causa di problemi di riallocazione della memoria, anche se non ricordo per certo. I * think * l'elenco Python utilizza un array ridimensionabile - * non * un elenco collegato. Tuttavia, potrebbe esserci qualche tipo di ottimizzazione dell'appendice. Una comprensione delle liste * probabilmente * prealloca l'intero array all'inizio. – Steve314