Obtenga la diferencia entre dos listas con entradas únicas
Tengo dos listas en Python:
temp1 = ['One', 'Two', 'Three', 'Four']
temp2 = ['One', 'Two']
Suponiendo que los elementos de cada lista son únicos, quiero crear una tercera lista con elementos de la primera lista que no están en la segunda lista:
temp3 = ['Three', 'Four']
¿Existen formas rápidas sin ciclos ni comprobaciones?
Para obtener elementos que están temp1
pero no temp2
( asumiendo la unicidad de los elementos en cada lista ):
In [5]: list(set(temp1) - set(temp2))
Out[5]: ['Four', 'Three']
Cuidado que es asimétrico:
In [5]: set([1, 2]) - set([2, 3])
Out[5]: set([1])
donde podría esperar/querer que sea igual set([1, 3])
. Si quieres set([1, 3])
como respuesta, puedes usar set([1, 2]).symmetric_difference(set([2, 3]))
.
Todas las soluciones existentes ofrecen uno u otro de:
- Más rápido que el rendimiento O(n*m).
- Preservar el orden de la lista de entrada.
Pero hasta ahora ninguna solución tiene ambas cosas. Si quieres ambos, prueba esto:
s = set(temp2)
temp3 = [x for x in temp1 if x not in s]
Prueba de rendimiento
import timeit
init = 'temp1 = list(range(100)); temp2 = [i * 2 for i in range(50)]'
print timeit.timeit('list(set(temp1) - set(temp2))', init, number = 100000)
print timeit.timeit('s = set(temp2);[x for x in temp1 if x not in s]', init, number = 100000)
print timeit.timeit('[item for item in temp1 if item not in temp2]', init, number = 100000)
Resultados:
4.34620224079 # ars' answer
4.2770634955 # This answer
30.7715615392 # matt b's answer
El método que presenté, además de preservar el orden, también es (ligeramente) más rápido que la resta de conjuntos porque no requiere la construcción de un conjunto innecesario. La diferencia de rendimiento sería más notable si la primera lista fuera considerablemente más larga que la segunda y si el hash fuera caro. Aquí hay una segunda prueba que demuestra esto:
init = '''
temp1 = [str(i) for i in range(100000)]
temp2 = [str(i * 2) for i in range(50)]
'''
Resultados:
11.3836875916 # ars' answer
3.63890368748 # this answer (3 times faster!)
37.7445402279 # matt b's answer
Se puede hacer usando el operador XOR de Python.
- Esto eliminará los duplicados en cada lista.
- Esto mostrará la diferencia entre temp1 y temp2 y temp2 y temp1.
set(temp1) ^ set(temp2)