2009-09-07 166 views

Respuesta

289
No

el más eficiente, pero con mucho, la forma más obvia de hacerlo es:

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

si la orden es importante que se puede hacer con las listas por comprensión como este:

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

(solo funciona para listas de igual tamaño, lo que implica significado de orden).

+5

Una nota de precaución, la lista por comprensión cuenta no es necesariamente la opción más rápida. Para conjuntos más grandes (donde el rendimiento es más probable que importe), la comparación bit a bit ('&') o 'set (a) .intersection (b)' será tan rápida o más rápida que la comprensión de la lista. – Joshmaker

+5

Otra nota de precaución: la lista de comprensión encuentra los valores que aparecen en ambas en las MISMAS posiciones (esto es lo que SilentGhost quería decir con "el orden es significativo"). Las soluciones de intersección establecidas también encontrarán coincidencias en las posiciones DIFERENTES. Estas son respuestas a 2 preguntas bastante diferentes ... (la pregunta de la operación es ambigua en cuanto a lo que pregunta) – drevicko

+0

¿Cómo se hace esto si sus listas son listas de listas, es decir, a = [[0,0], [1, 0]] yb = [[2,3], [0,0]] – Schneems

11

La forma más sencilla de hacerlo es utilizar sets:

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

Uso set.intersection(), es rápido y fácil de leer.

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

Esta respuesta tiene un buen rendimiento algorítmico, ya que solo una de las listas (más corta se debe preferir) se convierte en un conjunto para búsqueda rápida, y la otra lista se recorre buscando sus elementos en el conjunto. – u0b34a0f6ae

+3

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

+0

Esta respuesta es más flexible y legible, ya que las personas pueden necesitar ['difference'] (https: //docs.python. org/3/library/stdtypes.html # frozenset.difference) o ['union'] (https://docs.python.org/3/library/stdtypes.html#frozenset.union). –

5

¿Quieres duplicados? Si no es así tal vez debería utilizar conjuntos de lugar:


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

Si realmente desea listas, http://www.java2s.com/Code/Python/List/Functiontointersecttwolists.htm >>> intersectar ([1, 2, 3, 4, 5], [9, 8, 7, 6, 5]) [5] –

+0

De acuerdo con el documento - * ... excluye construcciones propensas a errores como Set ('abc') y 'cbs' a favor del Set más legible ('abc'). intersection ('cbs'). * - http://docs.python.org/library/sets.html –

3

Usted puede utilizar

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 respuesta aceptada no funciona para las listas que contienen cadenas. Este lo hace – Antony

39

prefiero las respuestas basadas en conjunto, pero aquí es uno que funciona de todos modos

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

también Puedes probar esto, manteniendo los elementos comunes en una nueva lista.

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

Una prueba de rendimiento rápida mostrando solución de Lutz es el mejor:

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) 

Estos son los resultados en mi máquina:

# 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 

Obviamente, cualquier prueba de rendimiento artificial debe tomarse con un grano de sal, pero desde la respuesta set().intersection() es al menos tan rápido como las otras soluciones, y también la más readab le, debería ser la solución estándar para este problema común.

1

Se puede utilizar:

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

Salida:

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

¿En qué se diferencia esto de la respuesta aceptada de hace más de 6 años? – tom

+1

Bueno, escribí el detalle completo con salida y bueno para principiante python –

1

otra manera un poco más funcional para comprobar la igualdad de la lista de la lista 1 (lst1) y la lista 2 (LST2) donde los objetos tienen la profundidad uno y que mantiene la orden es:

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

Puede utilizar itertools.product también.

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

Si desea un valor 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

Usando __and__ método atributo también funciona.

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

o simplemente

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

Si bien este código puede responder a la pregunta, proporcionar un contexto adicional sobre cómo y/o por qué resuelve el problema mejoraría el valor a largo plazo de la respuesta. –

Cuestiones relacionadas