tuplas - Python encuentra elementos en una lista que no están en la otra
sacar elementos de una lista python (10)
(1) Puede usar
setdiff1d
de NumPy.
De la
respuesta de Chinny84
, si le preocupan los elementos
únicos
, entonces:
import numpy as np
list_1 = ["a", "b", "c", "d", "e"]
list_2 = ["a", "f", "c", "m"]
main_list = np.setdiff1d(list_2,list_1)
(2) De lo contrario, use
main_list = np.setdiff1d(list_2,list_1, assume_unique=True)
Ambas respuestas te darán
["f", "m"]
.
Sin embargo, si
list_2 = ["a", "f", "c", "m", "m"]
, la respuesta (1) produce
["f", "m"]
PERO la respuesta (2) da
["f", "m", "m"]
(porque la unicidad de cada elemento en
list_2
es irrelevante).
python numpy
Necesito comparar dos listas para crear una nueva lista de elementos específicos que se encuentran en una lista pero no en la otra. Por ejemplo:
main_list=[]
list_1=["a", "b", "c", "d", "e"]
list_2=["a", "f", "c", "m"]
Quiero recorrer list_1 y agregar a main_list todos los elementos de list_2 que no se encuentran en list_1.
El resultado debería ser:
main_list=["f", "m"]
¿Cómo puedo hacerlo con Python?
De ser1 elimine los elementos presentes en ser2.
Entrada
ser1 = pd.Series ([1, 2, 3, 4, 5]) ser2 = pd.Series ([4, 5, 6, 7, 8])
Solución
ser1 [~ ser1.isin (ser2)]
No estoy seguro de por qué las explicaciones anteriores son tan complicadas cuando tiene métodos nativos disponibles:
main_list = list(set(list_2)-set(list_1))
Puedes usar conjuntos:
main_list = list(set(list_2) - set(list_1))
Salida:
>>> list_1=["a", "b", "c", "d", "e"]
>>> list_2=["a", "f", "c", "m"]
>>> set(list_2) - set(list_1)
set([''m'', ''f''])
>>> list(set(list_2) - set(list_1))
[''m'', ''f'']
Según el comentario de @JonClements, aquí hay una versión más ordenada:
>>> list_1=["a", "b", "c", "d", "e"]
>>> list_2=["a", "f", "c", "m"]
>>> list(set(list_2).difference(list_1))
[''m'', ''f'']
Si desea una solución de una línea (ignorando las importaciones) que solo requiere trabajo
O(max(n, m))
para entradas de longitud
n
m
, no trabajo
O(n * m)
, puede hacerlo con
el módulo
itertools
:
from itertools import filterfalse
main_list = list(filterfalse(set(list_1).__contains__, list_2))
Esto aprovecha las funciones funcionales que toman una función de devolución de llamada en la construcción, lo que le permite crear la devolución de llamada una vez y reutilizarla para cada elemento sin necesidad de almacenarla en algún lugar (porque
filterfalse
almacena internamente);
las comprensiones de listas y las expresiones generadoras pueden hacer esto, pero es feo. †
Eso obtiene los mismos resultados en una sola línea que:
main_list = [x for x in list_2 if x not in list_1]
con la velocidad de:
set_1 = set(list_1)
main_list = [x for x in list_2 if x not in set_1]
Por supuesto, si las comparaciones pretenden ser posicionales, entonces:
list_1 = [1, 2, 3]
list_2 = [2, 3, 4]
debe producir:
main_list = [2, 3, 4]
(debido a que el valor en
list_2
tiene una coincidencia en el mismo índice en
list_1
), definitivamente debe ir con
la respuesta de Patrick
, que no implica una
list
temporal s o
set
s (incluso si el
set
s es aproximadamente
O(1)
, tienen un " "factor constante por comprobación que las comprobaciones de igualdad simples) e implica un trabajo
O(min(n, m))
, menos que cualquier otra respuesta, y si su problema es sensible a la posición, es la única solución
correcta
cuando los elementos coincidentes aparecen en compensaciones no coincidentes.
†: La manera de hacer lo mismo con una comprensión de la lista como una línea sería abusar del bucle anidado para crear y almacenar valores en el bucle "más externo", por ejemplo:
main_list = [x for set_1 in (set(list_1),) for x in list_2 if x not in set_1]
lo que también brinda un beneficio de rendimiento menor en Python 3 (porque ahora
set_1
tiene un alcance local en el código de comprensión, en lugar de
set_1
desde el alcance anidado para cada verificación; en Python 2 eso no importa, porque Python 2 no usa cierres para la comprensión de listas; operan en el mismo ámbito en el que se usan).
Si se debe tener en cuenta el número de ocurrencias, probablemente necesite usar algo como
collections.Counter
.
list_1=["a", "b", "c", "d", "e"]
list_2=["a", "f", "c", "m"]
from collections import Counter
cnt1 = Counter(list_1)
cnt2 = Counter(list_2)
final = [key for key, counts in cnt2.items() if cnt1.get(key, 0) != counts]
>>> final
[''f'', ''m'']
Como se prometió, esto también puede manejar diferentes números de ocurrencias como "diferencia":
list_1=["a", "b", "c", "d", "e", ''a'']
cnt1 = Counter(list_1)
cnt2 = Counter(list_2)
final = [key for key, counts in cnt2.items() if cnt1.get(key, 0) != counts]
>>> final
[''a'', ''f'', ''m'']
Usé dos métodos y encontré un método útil sobre otro. Aquí está mi respuesta:
Mis datos de entrada:
crkmod_mpp = [''M13'',''M18'',''M19'',''M24'']
testmod_mpp = [''M13'',''M14'',''M15'',''M16'',''M17'',''M18'',''M19'',''M20'',''M21'',''M22'',''M23'',''M24'']
np.setdiff1d
:
np.setdiff1d
Me gusta este enfoque sobre otro porque conserva la posición
test= list(np.setdiff1d(testmod_mpp,crkmod_mpp))
print(test)
[''M15'', ''M16'', ''M22'', ''M23'', ''M20'', ''M14'', ''M17'', ''M21'']
Método 2: aunque da la misma respuesta que en el Método 1 pero perturba el orden
test = list(set(testmod_mpp).difference(set(crkmod_mpp)))
print(test)
[''POA23'', ''POA15'', ''POA17'', ''POA16'', ''POA22'', ''POA18'', ''POA24'', ''POA21'']
Method1
np.setdiff1d
cumple mis requisitos perfectamente.
Esta respuesta para información.
Use una lista de comprensión como esta:
main_list = [item for item in list_2 if item not in list_1]
Salida:
>>> list_1 = ["a", "b", "c", "d", "e"]
>>> list_2 = ["a", "f", "c", "m"]
>>>
>>> main_list = [item for item in list_2 if item not in list_1]
>>> main_list
[''f'', ''m'']
Editar:
Como se menciona en los comentarios a continuación, con grandes listas, lo anterior no es la solución ideal.
Cuando ese sea el caso, una mejor opción sería convertir
list_1
a un
set
primero:
set_1 = set(list_1) # this reduces the lookup time from O(n) to O(1)
main_list = [item for item in list_2 if item not in set_1]
zip
las listas juntas para compararlas elemento por elemento.
main_list = [b for a, b in zip(list1, list2) if a!= b]
main_list=[]
list_1=["a", "b", "c", "d", "e"]
list_2=["a", "f", "c", "m"]
for i in list_2:
if i not in list_1:
main_list.append(i)
print(main_list)
salida:
[''f'', ''m'']