2017-01-23 5 views
11

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

ответ

11

можно пересчитать вхождения в список понимания, превращая их в tuple, так что вы можете хэширования & применять единственность:

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)) 
+1

nitpick: удалить '[]' из '' '' '' '' ', чтобы использовать более быстрое выражение генератора – Harvey

+0

определенно не nitpick !! Я так привык к «.» .Join ([]) 'to_speed up_' join' ... –

+0

@Donald: также, если желание состоит только в удалении дубликатов, тогда просто: 'set (tuple (x) для x в маршрутах) ' – Harvey

3
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)) 
+0

вы получите сообщение дважды. –

+0

@ Jean-FrançoisFabre ahh, вы правы, позвольте мне исправить это. Спасибо, что указали, что нет –

+0

@ Jean-FrançoisFabre ха-ха да, поскольку практика не самая умная вещь, однако, в сокращении списка, как это, не так много вещей, которые могут пойти не так с этим. –

0
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) 

надеюсь, что это помогает!

0
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 

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

2

Не уверен, что если вы хотите внешнюю библиотеку, но у меня есть один, который содержит функцию явно для этой цели: 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