Combinar dos listas y eliminar duplicados, sin eliminar duplicados en la lista original


115

Tengo dos listas que necesito combinar donde la segunda lista tiene cualquier duplicado de la primera lista ignorado. .. Un poco difícil de explicar, así que déjame mostrarte un ejemplo de cómo se ve el código y lo que quiero como resultado.

first_list = [1, 2, 2, 5]

second_list = [2, 5, 7, 9]

# The result of combining the two lists should result in this list:
resulting_list = [1, 2, 2, 5, 7, 9]

Notará que el resultado tiene la primera lista, incluidos sus dos valores "2", pero el hecho de que second_list también tiene un valor adicional de 2 y 5 no se agrega a la primera lista.

Normalmente, para algo como esto, usaría conjuntos, pero un conjunto en first_list eliminaría los valores duplicados que ya tiene. Así que simplemente me pregunto cuál es la mejor / más rápida forma de lograr esta combinación deseada.

Gracias.


3
¿Qué pasa si hay tres 2 en second_list?
balpha

@balpha: Sí, todavía no he decidido por completo cómo quiero manejar eso. Es algo en lo que había pensado, pero lo dejé de lado dada mi indecisión al respecto :)
Lee Olayvar

Respuestas:


168

Debe agregar a la primera lista los elementos de la segunda lista que no están en la primera; los conjuntos son la forma más fácil de determinar qué elementos son, así:

first_list = [1, 2, 2, 5]
second_list = [2, 5, 7, 9]

in_first = set(first_list)
in_second = set(second_list)

in_second_but_not_in_first = in_second - in_first

result = first_list + list(in_second_but_not_in_first)
print(result)  # Prints [1, 2, 2, 5, 9, 7]

O si lo prefiere de una sola línea 8-)

print(first_list + list(set(second_list) - set(first_list)))

2
O esto si lo necesita ordenado: imprima first_list + sorted (set (second_list) - set (first_list))
hughdbrown

2
Lista (conjunto (primera_lista) | conjunto (segunda_lista)) # | se establece intersección ver stackoverflow.com/questions/4674013/…
staticd

1
@staticd: Sí, pero eso da una respuesta incorrecta. Solo hay uno 2en su resultado, cuando debería haber dos de ellos.
RichieHindle

Ups. Tienes razón. Perdí por completo que se permitieran duplicados a la primera lista . : P
staticd

66
resulting_list = list(first_list)
resulting_list.extend(x for x in second_list if x not in resulting_list)

7
¡Finalmente una respuesta que no implica lanzar conjuntos! Prestigio.
SuperFamousGuy

4
esto es, de hecho, O (n * m) pero puede ser útil cuando tienes una lista de cosas que no se pueden mezclar y el rendimiento no es una preocupación
alcuadrado

1
¿Qué no quiero que se duplique ni del primero ni del segundo?
Dejell

Esta técnica conserva el orden de los atributos en la lista, lo que no es el caso de set. 👍
Subhash Bhushan

29

Puedes usar conjuntos:

first_list = [1, 2, 2, 5]
second_list = [2, 5, 7, 9]

resultList= list(set(first_list) | set(second_list))

print(resultList)
# Results in : resultList = [1,2,5,7,9]

Sí, gracias lo tengo. Esto funcionará bien. resultList = first_list + list (set (second_list) -set (first_list))
Kathiravan Umaidurai

9

Puede reducir esto a una sola línea de código si usa numpy:

a = [1,2,3,4,5,6,7]
b = [2,4,7,8,9,10,11,12]

sorted(np.unique(a+b))

>>> [1,2,3,4,5,6,7,8,9,10,11,12]

7
first_list = [1, 2, 2, 5]
second_list = [2, 5, 7, 9]

print( set( first_list + second_list ) )

5
resulting_list = first_list + [i for i in second_list if i not in first_list]

1
setify first_list y estará "listo"
u0b34a0f6ae

La lista resultante no se ordenará.
Avakar

1
¿Qué sucede si tampoco quiero que ninguna lista tenga duplicados? de esta manera, si una lista tiene duplicados, regresarán
Dejell

5

Lo más simple para mí es:

first_list = [1, 2, 2, 5]
second_list = [2, 5, 7, 9]

merged_list = list(set(first_list+second_list))
print(merged_list)

#prints [1, 2, 5, 7, 9]

1
Esa es una gran solución, pero tenga en cuenta que no funcionará si intentamos hacer un conjunto de diccionarios, por ejemplo, (aumentará TypeError: unhashable type: 'dict')
lakesare

2

También puede combinar las respuestas de RichieHindle y Ned Batchelder para un algoritmo O (m + n) de caso promedio que preserva el orden:

first_list = [1, 2, 2, 5]
second_list = [2, 5, 7, 9]

fs = set(first_list)
resulting_list = first_list + [x for x in second_list if x not in fs]

assert(resulting_list == [1, 2, 2, 5, 7, 9])

Tenga en cuenta que x in stiene una complejidad en el peor de los casos de O (m) , por lo que la complejidad del peor de los casos de este código sigue siendo O (m * n) .


0

Esto puede ayudar

def union(a,b):
    for e in b:
        if e not in a:
            a.append(e)

La función de unión fusiona la segunda lista con la primera, sin duplicar un elemento de a, si ya está en a. Similar a establecer un operador de unión. Esta función no cambia b. Si a = [1,2,3] b = [2,3,4]. Después de la unión (a, b) hace a = [1,2,3,4] yb = [2,3,4]


0

Basado en la receta :

lista_resultantes = lista (conjunto (). unión (primera_lista, segunda_lista))


-2
    first_list = [1, 2, 2, 5]
    second_list = [2, 5, 7, 9]

    newList=[]
    for i in first_list:
        newList.append(i)
    for z in second_list:
        if z not in newList:
            newList.append(z)
    newList.sort()
    print newList

[1, 2, 2, 5, 7, 9]

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.