Por ejemplo, dada la lista ['one', 'two', 'one']
, el algoritmo debería regresar True
, mientras que dado ['one', 'two', 'three']
que debería regresar False
.
python
string
list
duplicates
teggy
fuente
fuente
Recomendado solo para listas cortas :
No lo use en una lista larga: ¡puede llevar un tiempo proporcional al cuadrado del número de elementos en la lista!
Para listas más largas con elementos que se pueden compartir (cadenas, números, etc.):
Si sus artículos no son intercambiables (sublistas, dictados, etc.) se vuelve más complicado, aunque aún es posible obtener O (N logN) si son al menos comparables. Pero debe conocer o probar las características de los elementos (hashable o no, comparable o no) para obtener el mejor rendimiento posible: O (N) para hashables, O (N log N) para comparables no hashaable, de lo contrario se reduce a O (N al cuadrado) y no hay nada que se pueda hacer al respecto :-(.
fuente
all
recuento, siendo todos 1). Un dict con todos los valores True, que también mencionas, es un mimetismo ridículamente inútil de aset
, sin ningún valor agregado. Big-O no lo es todo en programación.Esto es viejo, pero las respuestas aquí me llevaron a una solución ligeramente diferente. Si está dispuesto a abusar de las comprensiones, puede hacer un cortocircuito de esta manera.
fuente
Si eres aficionado al estilo de programación funcional, aquí hay una función útil, código auto documentado y probado usando doctest .
Desde allí, puede probar la unicidad comprobando si el segundo elemento del par devuelto está vacío:
Tenga en cuenta que esto no es eficiente ya que está construyendo explícitamente la descomposición. Pero en la línea del uso de reducir, puede llegar a algo equivalente (pero un poco menos eficiente) para responder 5:
fuente
Pensé que sería útil comparar los tiempos de las diferentes soluciones presentadas aquí. Para esto utilicé mi propia biblioteca
simple_benchmark
:De hecho, para este caso, la solución de Denis Otkidach es la más rápida.
Algunos de los enfoques también exhiben una curva mucho más pronunciada, estos son los enfoques que se escalan de forma cuadrática con el número de elementos (la primera solución de Alex Martellis, wjandrea y ambas soluciones de Xavier Decorets). También es importante mencionar que la solución de pandas de Keiku tiene un factor constante muy grande. Pero para listas más grandes casi se pone al día con las otras soluciones.
Y en caso de que el duplicado esté en la primera posición. Esto es útil para ver qué soluciones están en cortocircuito:
Aquí varios enfoques no provocan un cortocircuito: Kaiku, Frank, Xavier_Decoret (primera solución), Turn, Alex Martelli (primera solución) y el enfoque presentado por Denis Otkidach (que fue el más rápido en el caso sin duplicado).
Incluí una función de mi propia biblioteca aquí:
iteration_utilities.all_distinct
que puede competir con la solución más rápida en el caso de no duplicados y funciona en tiempo constante para el caso de duplicar al comienzo (aunque no tan rápido).El código para el punto de referencia:
Y por los argumentos:
fuente
Hace poco respondí una pregunta relacionada para establecer todos los duplicados en una lista, usando un generador. Tiene la ventaja de que si se usa solo para establecer "si hay un duplicado", entonces solo necesita obtener el primer elemento y el resto puede ignorarse, que es el último atajo.
Este es un enfoque interesante basado en conjuntos que adapté directamente de moooeeeep :
En consecuencia, una lista completa de engaños sería
list(getDupes(etc))
. Para probar simplemente "si" hay un engañado, debe envolverse de la siguiente manera:Esto escala bien y proporciona tiempos de operación consistentes donde sea que esté el engañado en la lista: probé con listas de hasta 1 millón de entradas. Si sabe algo sobre los datos, específicamente, que es probable que aparezcan duplicados en la primera mitad u otras cosas que le permitan sesgar sus requisitos, como la necesidad de obtener los duplicados reales, entonces hay un par de localizadores de duplicados realmente alternativos eso podría superar. Los dos que recomiendo son ...
Enfoque simple basado en dict, muy legible:
Aproveche las herramientas iterativas (esencialmente un ifilter / izip / tee) en la lista ordenada, muy eficiente si está obteniendo todos los engaños, aunque no tan rápido para obtener solo el primero:
Estos fueron los mejores resultados de los enfoques que probé para la lista completa de duplicados , con el primer duplicado en cualquier lugar de una lista de elementos de 1 m desde el principio hasta el medio. Fue sorprendente lo poco que sobrepasó el paso de clasificación. Su millaje puede variar, pero aquí están mis resultados específicos cronometrados:
fuente
.next()
llamada en su segundo bloque de código no funciona en Python 3.x. Creo quenext(getDupes(l))
debería funcionar en todas las versiones de Python, por lo que puede tener sentido cambiar eso.ifilter
yìzip
puede ser simplemente reemplazado por el incorporadofilter
yzip
en Python 3.x.Otra forma de hacerlo de manera sucinta es con Counter .
Para determinar si hay duplicados en la lista original:
O para obtener una lista de elementos que tienen duplicados:
fuente
fuente
Encontré que esto hace el mejor rendimiento porque cortocircuita la operación cuando se encuentra el primer duplicado, luego este algoritmo tiene una complejidad de tiempo y espacio O (n) donde n es la longitud de la lista:
fuente
Realmente no sé qué set hace detrás de escena, así que solo quiero que sea simple.
fuente
Una solución más simple es la siguiente. Simplemente marque Verdadero / Falso con el
.duplicated()
método pandas y luego tome la suma. Consulte también pandas.Series.duplicated - documentación de pandas 0.24.1fuente
Si la lista contiene elementos no compartibles, puede usar la solución de Alex Martelli pero con una lista en lugar de un conjunto, aunque es más lenta para entradas más grandes: O (N ^ 2).
fuente
Utilicé el enfoque de pyrospade, por su simplicidad, y lo modifiqué ligeramente en una lista corta hecha del registro de Windows que no distingue entre mayúsculas y minúsculas.
Si la cadena de valor de RUTA sin procesar se divide en rutas individuales, todas las rutas 'nulas' (cadenas vacías o de espacio en blanco) pueden eliminarse utilizando:
La RUTA original tiene entradas 'nulas' y duplicadas para fines de prueba:
Se han eliminado las rutas nulas, pero todavía tiene duplicados, por ejemplo, (1, 3) y (13, 20):
Y finalmente, los engañados han sido eliminados:
fuente
fuente