2009-09-07 15 views

risposta

289
Non

la più efficiente, ma di gran lunga il modo più ovvio per farlo è:

>>> a = [1, 2, 3, 4, 5] 
>>> b = [9, 8, 7, 6, 5] 
>>> set(a) & set(b) 
{5} 

se l'ordine è significativo lo si può fare con la list comprehension come questo:

>>> [i for i, j in zip(a, b) if i == j] 
[5] 

(Funziona solo con elenchi di dimensioni uguali, il che implica il significato degli ordini).

+5

Una nota di cautela, l'elenco di comprensione * non * è necessariamente l'opzione più veloce. Per i set più grandi (dove è più probabile che le prestazioni abbiano importanza) il confronto bit a bit ('&') o 'set (a) .intersection (b)' sarà più veloce o più veloce della comprensione delle liste. – Joshmaker

+5

Un'altra nota di cautela: la list comprehension trova i valori che appaiono in entrambe le posizioni SAME (questo è ciò che SilentGhost intendeva per "l'ordine è significativo"). Le soluzioni di intersezione impostate troveranno anche corrispondenze in posizioni DIFFERENTI. Queste sono le risposte a 2 domande abbastanza diverse ... (la domanda dell'op è ambigua riguardo a quale si sta chiedendo) – drevicko

+0

Come si fa se le proprie liste sono liste di liste, cioè a = [[0,0], [1, 0]] eb = [[2,3], [0,0]] – Schneems

11

Il modo più semplice per farlo è quello di utilizzare sets:

>>> a = [1, 2, 3, 4, 5] 
>>> b = [9, 8, 7, 6, 5] 
>>> set(a) & set(b) 
set([5]) 
260

Usa set.intersection(), è veloce e leggibile.

>>> set(a).intersection(b) 
set([5]) 
+22

Questa risposta ha buone prestazioni algoritmiche, in quanto solo uno degli elenchi (più breve deve essere preferito) viene trasformato in un set per la ricerca rapida e l'altro elenco viene attraversato alla ricerca dei suoi elementi nel set. – u0b34a0f6ae

+3

'bool (set (a) .intersection (b))' per 'True' o' False' – Akshay

+0

Questa risposta è più flessibile e leggibile, dal momento che le persone potrebbero aver bisogno di ['difference'] (https: //docs.python. org/3/library/stdtypes.html # frozenset.difference) o ['union'] (https://docs.python.org/3/library/stdtypes.html#frozenset.union). –

5

Vuoi duplicati? Se non forse si dovrebbe utilizzare i set, invece:


>>> set([1, 2, 3, 4, 5]).intersection(set([9, 8, 7, 6, 5])) 
set([5]) 
+0

Se si vuole veramente liste, http://www.java2s.com/Code/Python/List/Functiontointersecttwolists.htm >>> intersecano ([1, 2, 3, 4, 5], [9, 8, 7, 6, 5]) [5] –

+0

Secondo il doc - * ... preclude le costruzioni soggette a errori come Set ('abc') e 'cbs' in favore del Set più leggibile ('abc'). intersezione ('cbs'). * - http://docs.python.org/library/sets.html –

3

È possibile utilizzare

def returnMatches(a,b): 
     return list(set(a) & set(b)) 
9
>>> s = ['a','b','c'] 
>>> f = ['a','b','d','c'] 
>>> ss= set(s) 
>>> fs =set(f) 
>>> print ss.intersection(fs) 
    **set(['a', 'c', 'b'])** 
>>> print ss.union(fs)   
    **set(['a', 'c', 'b', 'd'])** 
>>> print ss.union(fs) - ss.intersection(fs) 
    **set(['d'])** 
+0

La risposta accettata non funziona per gli elenchi che contengono stringhe. Questo fa. – Antony

39

preferisco il set base di risposte, ma ecco quello che funziona in ogni caso

[x for x in a if x in b] 
8

anche puoi provare questo, mantenendo gli elementi comuni in una nuova lista.

new_list = [] 
for element in a: 
    if element in b: 
     new_list.append(element) 
64

Un test di prestazione rapida che mostra la soluzione di Lutz è il migliore:

import time 

def speed_test(func): 
    def wrapper(*args, **kwargs): 
     t1 = time.time() 
     for x in xrange(5000): 
      results = func(*args, **kwargs) 
     t2 = time.time() 
     print '%s took %0.3f ms' % (func.func_name, (t2-t1)*1000.0) 
     return results 
    return wrapper 

@speed_test 
def compare_bitwise(x, y): 
    set_x = frozenset(x) 
    set_y = frozenset(y) 
    return set_x & set_y 

@speed_test 
def compare_listcomp(x, y): 
    return [i for i, j in zip(x, y) if i == j] 

@speed_test 
def compare_intersect(x, y): 
    return frozenset(x).intersection(y) 

# Comparing short lists 
a = [1, 2, 3, 4, 5] 
b = [9, 8, 7, 6, 5] 
compare_bitwise(a, b) 
compare_listcomp(a, b) 
compare_intersect(a, b) 

# Comparing longer lists 
import random 
a = random.sample(xrange(100000), 10000) 
b = random.sample(xrange(100000), 10000) 
compare_bitwise(a, b) 
compare_listcomp(a, b) 
compare_intersect(a, b) 

Questi sono i risultati sulla mia macchina:

# Short list: 
compare_bitwise took 10.145 ms 
compare_listcomp took 11.157 ms 
compare_intersect took 7.461 ms 

# Long list: 
compare_bitwise took 11203.709 ms 
compare_listcomp took 17361.736 ms 
compare_intersect took 6833.768 ms 

Ovviamente, qualsiasi test delle prestazioni artificiale deve essere preso con un grano di sale, ma dal momento che la risposta set().intersection() è almeno altrettanto veloce come le altre soluzioni, e anche il più readab le, dovrebbe essere la soluzione standard per questo problema comune.

1

È possibile utilizzare:

a = [1, 3, 4, 5, 9, 6, 7, 8] 
b = [1, 7, 0, 9] 
same_values = set(a) & set(b) 
print same_values 

uscita:

set([1, 7, 9]) 
+3

in che modo è diverso dalla risposta accettata di 6 anni fa? – tom

+1

Bene, ho scritto il dettaglio completo con output e buono per principianti python –

1

un altro modo un po 'più funzionale per verificare l'uguaglianza lista per lista 1 (LST1) e la lista 2 (LST2), dove gli oggetti hanno la profondità uno e che mantiene l'ordine è:

all(i == j for i, j in zip(lst1, lst2)) 
3

Può utilizzare anche itertools.product.

>>> common_elements=[] 
>>> for i in list(itertools.product(a,b)): 
... if i[0] == i[1]: 
...  common_elements.append(i[0]) 
0

Se si desidera un valore booleano:

>>> a = [1, 2, 3, 4, 5] 
>>> b = [9, 8, 7, 6, 5] 
>>> set(b) == set(a) & set(b) and set(a) == set(a) & set(b) 
False 
>>> a = [3,1,2] 
>>> b = [1,2,3] 
>>> set(b) == set(a) & set(b) and set(a) == set(a) & set(b) 
True 
0

Utilizzando __and__ metodo attributo funziona anche.

>>> a = [1, 2, 3, 4, 5] 
>>> b = [9, 8, 7, 6, 5] 
>>> set(a).__and__(set(b)) 
set([5]) 

o semplicemente

>>> set([1, 2, 3, 4, 5]).__and__(set([9, 8, 7, 6, 5])) 
set([5]) 
>>>  
1
a = [1, 2, 3, 4, 5] 
b = [9, 8, 7, 6, 5] 

lista =set(a) 
listb =set(b) 
print listb.intersection(lista) 
returnMatches = set(['5']) #output 

print " ".join(str(return) for return in returnMatches) # remove the set() 

5  #final output 
+0

Mentre questo codice può rispondere alla domanda, fornire un contesto aggiuntivo su come e/o perché risolve il problema migliorerebbe il valore a lungo termine della risposta. –

Problemi correlati