unicos una repetidos lista identificar enlazada encontrar eliminar elementos contar array python

identificar - encontrar elementos repetidos en una lista python



Índice de elementos duplicados en una lista de Python (11)

Creo que encontré una solución simple después de mucha irritación:

if elem in string_list: counter = 0 elem_pos = [] for i in string_list: if i == elem: elem_pos.append(counter) counter = counter + 1 print(elem_pos)

Esto imprime una lista que le da los índices de un elemento específico ("elem")

¿Alguien sabe cómo puedo obtener la posición del índice de los elementos duplicados en una lista de Python? He intentado hacer esto y me sigue dando solo el índice de la primera aparición del ítem en la lista.

List = [''A'', ''B'', ''A'', ''C'', ''E'']

Quiero que me dé:

index 0: A index 2: A


Desea pasar el segundo parámetro opcional para indexar, la ubicación donde desea que el índice comience a buscarse. Después de encontrar cada coincidencia, restablezca este parámetro a la ubicación justo después de la coincidencia que se encontró.

def list_duplicates_of(seq,item): start_at = -1 locs = [] while True: try: loc = seq.index(item,start_at+1) except ValueError: break else: locs.append(loc) start_at = loc return locs source = "ABABDBAAEDSBQEWBAFLSAFB" print list_duplicates_of(source, ''B'')

Huellas dactilares:

[1, 3, 5, 11, 15, 22]

Puede encontrar todos los duplicados a la vez en un solo paso a través de la fuente, utilizando un valor predeterminado para mantener una lista de todas las ubicaciones vistas para cualquier artículo y devolver esos elementos que se vieron más de una vez.

from collections import defaultdict def list_duplicates(seq): tally = defaultdict(list) for i,item in enumerate(seq): tally[item].append(i) return ((key,locs) for key,locs in tally.items() if len(locs)>1) for dup in sorted(list_duplicates(source)): print dup

Huellas dactilares:

(''A'', [0, 2, 6, 7, 16, 20]) (''B'', [1, 3, 5, 11, 15, 22]) (''D'', [4, 9]) (''E'', [8, 13]) (''F'', [17, 21]) (''S'', [10, 19])

Si desea realizar pruebas repetidas para varias claves contra la misma fuente, puede usar functools.partial para crear una nueva variable de función, utilizando una lista de argumentos "parcialmente completa", es decir, especificando el seq, pero omitiendo el elemento para buscar para:

from functools import partial dups_in_source = partial(list_duplicates_of, source) for c in "ABDEFS": print c, dups_in_source(c)

Huellas dactilares:

A [0, 2, 6, 7, 16, 20] B [1, 3, 5, 11, 15, 22] D [4, 9] E [8, 13] F [17, 21] S [10, 19]


Guau, la respuesta de todos es muy larga. Simplemente utilicé un marco de datos de pandas , masking y la función duplicated ( keep=False marca todos los duplicados como True , no solo primero o último):

import pandas as pd import numpy as np np.random.seed(42) # make results reproducible int_df = pd.DataFrame({''int_list'': np.random.randint(1, 20, size=10)}) dupes = int_df[''int_list''].duplicated(keep=False) print(int_df[''int_list''][dupes].index)

Esto debería devolver Int64Index([0, 2, 3, 4, 6, 7, 9], dtype=''int64'') .


Hice un punto de referencia de todas las soluciones sugeridas aquí y también agregué otra solución a este problema (que se describe al final de la respuesta).

Puntos de referencia

Primero, los puntos de referencia. Inicializo una lista de n entradas aleatorias dentro de un rango [1, n/2] y luego call timeit sobre todos los algoritmos

Las soluciones de @ Paul McGuire y @ funcionan aproximadamente dos veces más rápido que el resto en la lista de 100 entradas:

Testing algorithm on the list of 100 items using 10000 loops Algorithm: dupl_eat Timing: 1.46247477189 #################### Algorithm: dupl_utdemir Timing: 2.93324529055 #################### Algorithm: dupl_lthaulow Timing: 3.89198786645 #################### Algorithm: dupl_pmcguire Timing: 0.583058259784 #################### Algorithm: dupl_ivazques_abrams Timing: 0.645062989076 #################### Algorithm: dupl_rbespal Timing: 1.06523873786 ####################

Si cambia el número de elementos a 1000, la diferencia se vuelve mucho más grande (por cierto, estaré feliz si alguien pudiera explicar por qué ):

Testing algorithm on the list of 1000 items using 1000 loops Algorithm: dupl_eat Timing: 5.46171654555 #################### Algorithm: dupl_utdemir Timing: 25.5582547323 #################### Algorithm: dupl_lthaulow Timing: 39.284285326 #################### Algorithm: dupl_pmcguire Timing: 0.56558489513 #################### Algorithm: dupl_ivazques_abrams Timing: 0.615980005148 #################### Algorithm: dupl_rbespal Timing: 1.21610942322 ####################

En las listas más grandes, la solución de @ Paul McGuire sigue siendo la más eficiente y mi algoritmo comienza a tener problemas.

Testing algorithm on the list of 1000000 items using 1 loops Algorithm: dupl_pmcguire Timing: 1.5019953958 #################### Algorithm: dupl_ivazques_abrams Timing: 1.70856155898 #################### Algorithm: dupl_rbespal Timing: 3.95820421595 ####################

El código completo del benchmark está here

Otro algoritmo

Aquí está mi solución al mismo problema:

def dupl_rbespal(c): alreadyAdded = False dupl_c = dict() sorted_ind_c = sorted(range(len(c)), key=lambda x: c[x]) # sort incoming list but save the indexes of sorted items for i in xrange(len(c) - 1): # loop over indexes of sorted items if c[sorted_ind_c[i]] == c[sorted_ind_c[i+1]]: # if two consecutive indexes point to the same value, add it to the duplicates if not alreadyAdded: dupl_c[c[sorted_ind_c[i]]] = [sorted_ind_c[i], sorted_ind_c[i+1]] alreadyAdded = True else: dupl_c[c[sorted_ind_c[i]]].append( sorted_ind_c[i+1] ) else: alreadyAdded = False return dupl_c

Aunque no es lo mejor, me permitió generar una estructura un poco diferente para mi problema (necesitaba algo así como una lista vinculada de índices del mismo valor)


Hola chicos, lo hago simple:

i = [1,2,1,3] k = 0 for ii in i: if ii == 1 : print ("index of 1 = ", k) k = k+1

salida:

índice de 1 = 0

índice de 1 = 2


Mencionaré la forma más obvia de tratar con duplicados en las listas. En términos de complejidad, los diccionarios son el camino a seguir porque cada búsqueda es O (1). Puede ser más inteligente si solo está interesado en duplicados ...

my_list = [1,1,2,3,4,5,5] my_dict = {} for (ind,elem) in enumerate(my_list): if elem in my_dict: my_dict[elem].append(ind) else: my_dict.update({elem:[ind]}) for key,value in my_dict.iteritems(): if len(value) > 1: print "key(%s) has indices (%s)" %(key,value)

que imprime lo siguiente:

key(1) has indices ([0, 1]) key(5) has indices ([5, 6])


Usando la nueva clase "Contador" en el módulo de colecciones, basado en la respuesta de lazyr:

>>> import collections >>> def duplicates(n): #n="123123123" ... counter=collections.Counter(n) #{''1'': 3, ''3'': 3, ''2'': 3} ... dups=[i for i in counter if counter[i]!=1] #[''1'',''3'',''2''] ... result={} ... for item in dups: ... result[item]=[i for i,j in enumerate(n) if j==item] ... return result ... >>> duplicates("123123123") {''1'': [0, 3, 6], ''3'': [2, 5, 8], ''2'': [1, 4, 7]}


>>> def duplicates(lst, item): ... return [i for i, x in enumerate(lst) if x == item] ... >>> duplicates(List, "A") [0, 2]

Para obtener todos los duplicados, puede usar el siguiente método, pero no es muy eficiente. Si la eficiencia es importante, debes considerar la solución de Ignacio.

>>> dict((x, duplicates(List, x)) for x in set(List) if List.count(x) > 1) {''A'': [0, 2]}

En cuanto a resolverlo usando el método de index de list lugar, ese método toma un segundo argumento opcional que indica por dónde empezar, por lo que podría llamarlo repetidamente con el índice anterior más 1.

>>> List.index("A") 0 >>> List.index("A", 1) 2

EDITAR Problema resuelto planteado en los comentarios.


dups = collections.defaultdict(list) for i, e in enumerate(L): dups[e].append(i) for k, v in sorted(dups.iteritems()): if len(v) >= 2: print ''%s: %r'' % (k, v)

Y extrapolar desde allí.


from collections import Counter, defaultdict def duplicates(lst): cnt= Counter(lst) return [key for key in cnt.keys() if cnt[key]> 1] def duplicates_indices(lst): dup, ind= duplicates(lst), defaultdict(list) for i, v in enumerate(lst): if v in dup: ind[v].append(i) return ind lst= [''a'', ''b'', ''a'', ''c'', ''b'', ''a'', ''e''] print duplicates(lst) # [''a'', ''b''] print duplicates_indices(lst) # ..., {''a'': [0, 2, 5], ''b'': [1, 4]})

Una implementación ligeramente más ortogonal (y por lo tanto más útil) sería:

from collections import Counter, defaultdict def duplicates(lst): cnt= Counter(lst) return [key for key in cnt.keys() if cnt[key]> 1] def indices(lst, items= None): items, ind= set(lst) if items is None else items, defaultdict(list) for i, v in enumerate(lst): if v in items: ind[v].append(i) return ind lst= [''a'', ''b'', ''a'', ''c'', ''b'', ''a'', ''e''] print indices(lst, duplicates(lst)) # ..., {''a'': [0, 2, 5], ''b'': [1, 4]})


string_list = [''A'', ''B'', ''C'', ''B'', ''D'', ''B''] pos_list = [] for i in range(len(string_list)): if string_list[i] = =''B'': pos_list.append(i) print pos_list