Eliminación de duplicados en las listas

Más o menos necesito escribir un programa que compruebe si una lista tiene duplicados y si los tiene los elimine y devuelva una nueva lista con los elementos que no estaban duplicados/eliminados. Esto es lo que tengo pero para ser sincero no se que hacer.

def remove_duplicates():
    t = ['a', 'b', 'c', 'd']
    t2 = ['a', 'c', 'd']
    for t in t2:
        t.append(t.remove())
    return t
Solución

El enfoque común para obtener una colección única de elementos es utilizar un set. Los conjuntos son colecciones desordenadas de objetos distintos. Para crear un conjunto a partir de cualquier iterable, puedes simplemente pasarlo a la función incorporada set(). Si más tarde necesitas una lista real de nuevo, puedes pasar el conjunto de forma similar a la función list().

El siguiente ejemplo debería cubrir cualquier cosa que estés intentando hacer:

>>> t = [1, 2, 3, 1, 2, 5, 6, 7, 8]
>>> t
[1, 2, 3, 1, 2, 5, 6, 7, 8]
>>> list(set(t))
[1, 2, 3, 5, 6, 7, 8]
>>> s = [1, 2, 3]
>>> list(set(t) - set(s))
[8, 5, 6, 7]

Como puede ver en el resultado del ejemplo, el orden original no se mantiene. Como se mencionó anteriormente, los conjuntos en sí mismos son colecciones desordenadas, por lo que el orden se pierde. Al volver a convertir un conjunto en una lista, se crea un orden arbitrario.

Mantener el orden

Si el orden es importante para usted, entonces tendrá que utilizar un mecanismo diferente. Una solución muy común para esto es confiar en OrderedDict para mantener el orden de las claves durante la inserción:

>>> from collections import OrderedDict
>>> list(OrderedDict.fromkeys(t))
[1, 2, 3, 5, 6, 7, 8]

A partir de Python 3.7, el diccionario incorporado está garantizado para mantener el orden de inserción también, por lo que también puede utilizarlo directamente si está en Python 3.7 o posterior (o CPython 3.6):

>>> list(dict.fromkeys(t))
[1, 2, 3, 5, 6, 7, 8]

Tenga en cuenta que esto tiene la sobrecarga de la creación de un diccionario en primer lugar, y luego la creación de una lista de la misma. Si no necesitas preservar el orden, es mejor que uses un conjunto. Consulta esta pregunta para más detalles y formas alternativas de preservar el orden al eliminar los duplicados.


Por último, ten en cuenta que tanto el set como las soluciones OrderedDict/dict requieren que tus elementos sean hashables. Esto normalmente significa que tienen que ser inmutables. Si tienes que tratar con elementos que no son hashable (por ejemplo, objetos de lista), entonces tendrás que utilizar un enfoque lento en el que básicamente tendrás que comparar cada elemento con cada otro elemento en un bucle anidado.

Comentarios (4)

Es una línea de un solo uso: list(set(source_list)) hará el truco.

Un set es algo que no puede tener duplicados.

Actualización: un enfoque que preserva el orden es de dos líneas:

from collections import OrderedDict
OrderedDict((x, True) for x in source_list).keys()

Aquí utilizamos el hecho de que OrderedDict recuerda el orden de inserción de las claves, y no lo cambia cuando se actualiza un valor en una clave concreta. Insertamos True como valores, pero podríamos insertar cualquier cosa, los valores simplemente no se utilizan. (set funciona como un dict con valores ignorados, también).

Comentarios (3)

Si no te importa el orden, haz esto:

def remove_duplicates(l):
    return list(set(l))

Se garantiza que un set no tiene duplicados.

Comentarios (1)