Проверка наличия дубликатов списков

дан список списков, я хочу убедиться, что нет двух списков, которые имеют одинаковые значения и порядок. Например, с 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

наслаждайтесь!