2012-10-31 29 views
5

Ecco cosa sto cercando di fare. Ho due liste di tuple. Creare un elenco di elementi in modo tale che il primo elemento di una tupla in list1 corrisponde al primo elemento di una tupla nella lista 2Confronto di elementi tra elementi in due liste di tuple

list1 = [('a', 2), ('b', 3), ('z', 5)] 

list2 = [('a', 1), ('b', 2), ('c', 3)] 

list3 = ['a','b'] 

Nota: Non ci possono essere duplicati primi elementi

Dopo aver guardato la lista di pitone comprensioni, questo è quello che ho fatto

[x[0] for x in list1 if (x[0] in [y[0] for y in list2])] 

Le mie domande è questo sarebbe come un programmatore esperto pitone sarebbe codificare questo in su? Dopo averlo codificato da solo, continuo a trovarlo abbastanza difficile da leggere. Se non altrimenti come lo faresti

+2

Qualora '[ 'a', 'b', 'c']' e '[ 'a', 'c']' 'partita' c''? –

+0

Direi di sì la lista finale sarebbe ['a', 'c'], ma nel mio esempio sto specificatamente guardando le liste di tuple – sidg11

+0

Puoi spiegare, cos'è "una tupla"? Non capisco una parola che dici di ciò che vuoi ottenere ... – Gandaro

risposta

8

userei zip():

In [25]: l1 = [('a', 2), ('b', 3), ('z', 5)] 

In [26]: l2 = [('a', 1), ('b', 2), ('c', 3)] 

In [27]: [x[0] for x,y in zip(l1,l2) if x[0]==y[0]] 
Out[27]: ['a', 'b'] 

EDIT: Dopo aver letto il tuo commento di cui sopra sembra che siete in cerca di qualcosa di simile:

In [36]: [x[0] for x in l1 if any(x[0]==y[0] for y in l2)] 
Out[36]: ['a', 'b'] 

o utilizzando sets:

In [43]: from operator import itemgetter 

In [44]: set(map(itemgetter(0),l1)) & set(map(itemgetter(0),l2)) 
Out[44]: set(['a', 'b']) 
+0

Dang! bastonami per 30 secondi. Nota: aumenterebbe le prestazioni con 'zip' all'esterno della comprensione della lista in modo che il' zip' non venisse ricalcolato ogni volta – inspectorG4dget

+0

@ inspectorG4dget Penso che 'zip()' venga chiamato solo una volta, dai un'occhiata al codice byte . –

+1

Hai ragione. Buona chiamata!'dis' ftw :) – inspectorG4dget

3

Penso che si desidera utilizzare set s qui:

set(x[0] for x in list1).intersection(y[0] for y in list2) 

o utilizzando zucchero sintattico:

{x[0] for x in list1} & {y[0] for y in list2} 

Entrambi che si traducono in:

set(['a', 'b']) 
2

penso che sia probabilmente più chiara per utilizzare gli insiemi qui (poiché non si dispone di elementi duplicati):

set1 = set(el[0] for el in list1) 
set2 = set(el[0] for el in list2) 
set3 = set1 & set2 # set intersection 
# list3 = list(set3) 
1

Supponendo che si desidera l'intersezione di set dei primi elementi delle tuple, è possibile usare il dizionario di vista principali introdotte in Python 2.7:

dict(list1).viewkeys() & dict(list2).viewkeys() 

Questo sarà molto più efficiente rispetto la soluzione per lunghi elenchi, poiché ha runtime lineare (a differenza di O (mn) per la soluzione), ma restituisce il risultato in ordine arbitrario (in contrapposizione all'ordine definito da list1).

In Python 3.x, questo sarebbe

dict(list1).keys() & dict(list2).keys() 
Problemi correlati