Проверка наличия списка дубликатов списков
Учитывая список списков, я хочу убедиться, что нет двух списков с одинаковыми значениями и порядком. Например, с 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
Ответы
Ответ 1
вы могли подсчитать вхождения в понимании списка, преобразовывая их в tuple
, чтобы вы могли хешировать и применять 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)
результат:
{(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)]
(Просто подсчитайте подстроки, преобразованные в кортеж, - устраните проблему хэширования - и создайте список дубликатов, используя список, сохраняя только элементы, которые появляются более одного раза)
Теперь, если вы просто хотите обнаружить, что есть несколько дубликатов списков (без их печати), вы могли бы
- преобразует список списков в список кортежей, чтобы вы могли хэш их в наборе
- сравните длину списка с длиной набора:
len отличается, если есть несколько дубликатов:
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))
Ответ 2
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))
Ответ 3
Не уверен, что вам нужна внешняя библиотека, но у меня есть функция, которая содержит функцию, явно созданную для этой цели: 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
Ответ 4
for x in routes:
print x, routes.count(x)
который вернет вам каждый список и сколько раз он появится.
alternativaly вы можете только показать, если они появляются > 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)
надеюсь, что это поможет!
Ответ 5
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
Наслаждайтесь!