Encontrar la intersección / diferencia entre las listas de python

Tengo dos listas de python:

a = [('when', 3), ('why', 4), ('throw', 9), ('send', 15), ('you', 1)] b = ['the', 'when', 'send', 'we', 'us'] 

Necesito filtrar todos los elementos de a que sean similares a los de b. Como en este caso, debería obtener:

 c = [('why', 4), ('throw', 9), ('you', 1)] 

¿Cuál debería ser la forma más efectiva?

Una lista de comprensión funcionará.

 a = [('when', 3), ('why', 4), ('throw', 9), ('send', 15), ('you', 1)] b = ['the', 'when', 'send', 'we', 'us'] filtered = [i for i in a if not i[0] in b] >>>print(filtered) [('why', 4), ('throw', 9), ('you', 1)] 

Una lista de comprensión debería funcionar:

 c = [item for item in a if item[0] not in b] 

O con un diccionario de comprensión:

 d = dict(a) c = {key: value for key in d.iteritems() if key not in b} 

Está bien, pero deberías usar conjuntos al menos para b . Si tiene adormecimiento, también puede probar np.in1d por supuesto, pero si es más rápido o no, probablemente debería intentarlo.

 # ruthless copy, but use the set... b = set(b) filtered = [i for i in a if not i[0] in b] # with numpy (note if you create the array like this, you must already put # the maximum string length, here 10), otherwise, just use an object array. # its slower (likely not worth it), but safe. a = np.array(a, dtype=[('key', 's10'), ('val', int)]) b = np.asarray(b) mask = ~np.in1d(a['key'], b) filtered = a[mask] 

Los conjuntos también tienen la difference métodos, etc., que probablemente no sean útiles aquí, pero en general probablemente lo sean.

Como esto está etiquetado con numpy , aquí hay una solución numpy que usa numpy.in1d comparada con la lista de comprensión:

 In [1]: a = [('when', 3), ('why', 4), ('throw', 9), ('send', 15), ('you', 1)] In [2]: b = ['the', 'when', 'send', 'we', 'us'] In [3]: a_ar = np.array(a, dtype=[('string','|S5'), ('number',float)]) In [4]: b_ar = np.array(b) In [5]: %timeit filtered = [i for i in a if not i[0] in b] 1000000 loops, best of 3: 778 ns per loop In [6]: %timeit filtered = a_ar[-np.in1d(a_ar['string'], b_ar)] 10000 loops, best of 3: 31.4 us per loop 

Así que para 5 registros la comprensión de la lista es más rápida.

Sin embargo, para grandes conjuntos de datos, la solución numpy es dos veces más rápida que la lista de comprensión:

 In [7]: a = a * 1000 In [8]: a_ar = np.array(a, dtype=[('string','|S5'), ('number',float)]) In [9]: %timeit filtered = [i for i in a if not i[0] in b] 1000 loops, best of 3: 647 us per loop In [10]: %timeit filtered = a_ar[-np.in1d(a_ar['string'], b_ar)] 1000 loops, best of 3: 302 us per loop 

Prueba esto :

 a = [('when', 3), ('why', 4), ('throw', 9), ('send', 15), ('you', 1)] b = ['the', 'when', 'send', 'we', 'us'] c=[] for x in a: if x[0] not in b: c.append(x) print c 

Demostración: http://ideone.com/zW7mzY

Utilizar filtro:

 c = filter(lambda (x, y): False if x in b else True, a)