python - tutorial - Verificando si una lista tiene listas duplicadas
para que se usa elastic search (5)
Dada una lista de listas, quiero asegurarme de que no haya dos listas que tengan los mismos valores y orden. Por ejemplo, con my_list = [[1, 2, 4, 6, 10], [12, 33, 81, 95, 110], [1, 2, 4, 6, 10]]
se supone que debe devolverme la existencia de listas duplicadas, es decir [1, 2, 4, 6, 10]
.
Usé el while
pero no funciona como quiero. ¿Alguien sabe cómo arreglar el código?
routes = [[1, 2, 4, 6, 10], [1, 3, 8, 9, 10], [1, 2, 4, 6, 10]]
r = len(routes) - 1
i = 0
while r != 0:
if cmp(routes[i], routes[i + 1]) == 0:
print "Yes, they are duplicate lists!"
r -= 1
i += 1
No estoy seguro si desea una biblioteca externa, pero tengo una que contiene una función explícitamente creada para este propósito: iteration_utilities.duplicates
>>> from iteration_utilities import duplicates
>>> my_list = [[1, 2, 4, 6, 10], [12, 33, 81, 95, 110], [1, 2, 4, 6, 10]]
>>> list(duplicates(my_list, key=tuple))
[[1, 2, 4, 6, 10]]
Tenga en cuenta que esto también funciona sin key=tuple
pero que tendrá un comportamiento O(n*n)
lugar de O(n)
.
>>> list(duplicates(my_list))
[[1, 2, 4, 6, 10]]
También mantiene el orden de aparición (con o sin key
) si eso es importante:
>>> list(duplicates([[1], [2], [3], [1], [2], [3]]))
[[1], [2], [3]]
Si solo está interesado si hay duplicados, puede usar any
en lugar de la list
:
>>> any(duplicates([[1], [2], [3], [1], [2], [3]]))
True
>>> any(duplicates([[1], [2], [3]]))
False
puede contar las ocurrencias en una lista de comprensión, convirtiéndolas en una tuple
para que pueda aplicar hash y aplicar unicity:
routes = [[1, 2, 4, 6, 10], [1, 3, 8, 9, 10], [1, 2, 4, 6, 10]]
dups = set(tuple(x) for x in routes if routes.count(x)>1)
print(dups)
resultado:
{(1, 2, 4, 6, 10)}
Bastante simple, pero un montón de bucles bajo el capó debido a las llamadas repetidas para count
. Hay otra manera, que implica hash pero tiene una complejidad menor sería usar collections.Counter
. collections.Counter
:
from collections import Counter
routes = [[1, 2, 4, 6, 10], [1, 3, 8, 9, 10], [1, 2, 4, 6, 10]]
c = Counter(map(tuple,routes))
dups = [k for k,v in c.items() if v>1]
print(dups)
Resultado:
[(1, 2, 4, 6, 10)]
(Solo cuente las sublistas convertidas en tuplas - solucionando el problema de hash - y genere una lista doble usando la comprensión de listas, manteniendo solo los elementos que aparecen más de una vez)
Ahora, si solo quiere detectar que hay algunas listas duplicadas (sin imprimirlas), podría
- convierta la lista de listas a una lista de tuplas para que pueda copiarlas en un conjunto
- compare la longitud de la lista con la longitud del conjunto:
len es diferente si hay algunos duplicados:
routes_tuple = [tuple(x) for x in routes]
print(len(routes_tuple)!=len(set(routes_tuple)))
o, poder usar el map
en Python 3 es lo suficientemente raro para ser mencionado así:
print(len(set(map(tuple,routes))) != len(routes))
def duplicate(lst):
cntrin=0
cntrout=0
for i in lst:
cntrin=0
for k in lst:
if i==k:
cntrin=cntrin+1
if cntrin>1:
cntrout=cntrout+1
if cntrout>0:
return True
else:
return False
¡Disfrutar!
for x in routes:
print x, routes.count(x)
eso te devolverá cada lista y cuántas veces aparece. alternativamente, solo puede mostrar si aparecen> 1:
new_list = []
for x in routes:
if routes.count(x)>1:
if x not in new_list:
new_list.append(x)
for x in new_list:
print x, routes.count(x)
¡Espero eso ayude!
routes = [[1, 2, 4, 6, 10], [1, 3, 8, 9, 10], [1, 2, 4, 6, 10]]
dups = set()
for route in routes:
if tuple(route) in dups:
print(''%s is a duplicate route'' % route)
else:
dups.add(tuple(route))