xticks barplot python list

python - barplot - Eliminar todos los elementos que aparecen en una lista de otra



pandas plot (6)

Digamos que tengo dos listas, l1 y l2 . Quiero realizar l1 - l2 , que devuelve todos los elementos de l1 no en l2 .

Puedo pensar en un enfoque de bucle ingenuo para hacer esto, pero va a ser realmente ineficiente. ¿Qué es una forma pitónica y eficiente de hacer esto?

Como ejemplo, si tengo l1 = [1,2,6,8] and l2 = [2,3,5,8] , l1 - l2 debería devolver [1,6]


Al ampliar la respuesta de Donut y las otras respuestas aquí, puede obtener resultados aún mejores si usa un generador de comprensión en lugar de una lista de comprensión, y si usa una estructura de datos set (ya que el operador in está en O (n) en una lista pero O ( 1) en un set).

Así que aquí hay una función que funcionaría para usted:

def filter_list(full_list, excludes): s = set(excludes) return (x for x in full_list if x not in s)

El resultado será un iterable que buscará perezosamente la lista filtrada. Si necesita un objeto de lista real (por ejemplo, si necesita hacer un len() en el resultado), puede crear fácilmente una lista así:

filtered_list = list(filter_list(full_list, excludes))


Como alternativa, también puede usar el filter con la expresión lambda para obtener el resultado deseado. Por ejemplo:

>>> l1 = [1,2,6,8] >>> l2 = set([2,3,5,8]) # v `filter` returns the a iterator object. Here I''m type-casting # v it to `list` in order to display the resultant value >>> list(filter(lambda x: x not in l2, l1)) [1, 6]

Comparación de rendimiento

Aquí estoy comparando el rendimiento de todas las respuestas mencionadas aquí. Como se esperaba, Arkku''s operación basada en el set Arkku''s es la más rápida.

  • Arkku''s : primero (0.124 usec por bucle)

    mquadri$ python -m timeit -s "l1 = set([1,2,6,8]); l2 = set([2,3,5,8]);" "l1 - l2" 10000000 loops, best of 3: 0.124 usec per loop

  • Lista de comprensión de Daniel Pryden con búsqueda de set - Segundo (0.302 usec por bucle)

    mquadri$ python -m timeit -s "l1 = [1,2,6,8]; l2 = set([2,3,5,8]);" "[x for x in l1 if x not in l2]" 1000000 loops, best of 3: 0.302 usec per loop

  • La comprensión de la lista de anillos en la lista simple - Tercero (0.552 usec por bucle)

    mquadri$ python -m timeit -s "l1 = [1,2,6,8]; l2 = [2,3,5,8];" "[x for x in l1 if x not in l2]" 1000000 loops, best of 3: 0.552 usec per loop

  • Moinuddin Quadri usando filter - Cuarto (0.972 usec por bucle)

    mquadri$ python -m timeit -s "l1 = [1,2,6,8]; l2 = set([2,3,5,8]);" "filter(lambda x: x not in l2, l1)" 1000000 loops, best of 3: 0.972 usec per loop

  • Akshay Hazari utiliza una combinación de reduce + filter - Quinto (3.97 usec por bucle)

    mquadri$ python -m timeit "l1 = [1,2,6,8]; l2 = [2,3,5,8];" "reduce(lambda x,y : filter(lambda z: z!=y,x) ,l1,l2)" 100000 loops, best of 3: 3.97 usec per loop

PS: set no mantiene el orden y elimina los elementos duplicados de la lista. Por lo tanto, no utilice la diferencia establecida si necesita alguno de estos.


Python tiene una función de lenguaje llamada Comprensiones de lista que es perfectamente adecuada para hacer que este tipo de cosas sea extremadamente fácil. La siguiente declaración hace exactamente lo que quiere y almacena el resultado en l3 :

l3 = [x for x in l1 if x not in l2]

l3 contendrá [1, 6] .

¡Espero que esto ayude!


Solución alternativa:

reduce(lambda x,y : filter(lambda z: z!=y,x) ,[2,3,5,8],[1,2,6,8])


Una forma es usar conjuntos:

>>> set([1,2,6,8]) - set([2,3,5,8]) set([1, 6])