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

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

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