Проверка наличия дубликатов списков
дан список списков, я хочу убедиться, что нет двух списков, которые имеют одинаковые значения и порядок. Например, с my_list = [[1, 2, 4, 6, 10], [12, 33, 81, 95, 110], [1, 2, 4, 6, 10]]
предполагается вернуть мне существование дубликатов списков, т. е. [1, 2, 4, 6, 10]
.
Я while
но он не работает как я хочу. Кто-нибудь знает как исправить этот код:
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
5 ответов
вы можете подсчитать вхождения в понимание списка, преобразуя их в tuple
таким образом, вы можете хэшировать и применять unicity:
routes = [[1, 2, 4, 6, 10], [1, 3, 8, 9, 10], [1, 2, 4, 6, 10]]
dups = {tuple(x) for x in routes if routes.count(x)>1}
print(dups)
результат:
{(1, 2, 4, 6, 10)}
достаточно просто, но много петель под капотом из-за повторных вызовов count
. Есть еще один способ, который включает в себя хэширование, но имеет меньшую сложность, будет использовать 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)
результат:
[(1, 2, 4, 6, 10)]
(просто подсчитайте кортеж-преобразованные подсписки - исправление проблемы хэширования-и создание списка dup с использованием понимания списка, сохраняя только элементы, которые появляются более одного раза)
теперь, если вы просто хотите обнаружить, что есть несколько дубликатов списков (без их печати), вы могли бы
- преобразуйте список списков в список кортежей, чтобы вы могли хэшировать их в наборе
- сравните длину списка с длиной набора:
лен отличается, если есть дубликаты:
routes_tuple = [tuple(x) for x in routes]
print(len(routes_tuple)!=len(set(routes_tuple)))
или, будучи в состоянии использовать map
в Python 3 достаточно редко упоминается так:
print(len(set(map(tuple,routes))) != len(routes))
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))
не уверен, хотите ли вы внешнюю библиотеку, но у меня есть одна, которая содержит функцию, явно сделанную для этой цели: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]]
обратите внимание, что это также работает без key=tuple
но это будет O(n*n)
поведение вместо O(n)
.
>>> list(duplicates(my_list))
[[1, 2, 4, 6, 10]]
он также сохраняет порядок появления (С или без key
), если это важно:
>>> list(duplicates([[1], [2], [3], [1], [2], [3]]))
[[1], [2], [3]]
если вы только заинтересованы если есть дубликаты, которые можно использовать any
на нем вместо list
:
>>> any(duplicates([[1], [2], [3], [1], [2], [3]]))
True
>>> any(duplicates([[1], [2], [3]]))
False
for x in routes:
print x, routes.count(x)
это вернет вам каждый список и сколько раз он появляется. альтернативно вы можете показать, только если они появляются > 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)
надеюсь, что это помогает!
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
наслаждайтесь!