2017-01-23 15 views
11

Đưa ra danh sách các danh sách, tôi muốn đảm bảo rằng không có hai danh sách có cùng giá trị và thứ tự. Ví dụ: my_list = [[1, 2, 4, 6, 10], [12, 33, 81, 95, 110], [1, 2, 4, 6, 10]], đó là nghĩa vụ trả lại cho tôi danh sách trùng lặp, tức là [1, 2, 4, 6, 10].Kiểm tra xem danh sách có danh sách trùng lặp hay không

Tôi đã sử dụng while nhưng nó không hoạt động như tôi muốn. Có ai biết làm thế nào để sửa chữa các mã:

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 

Trả lời

11

bạn có thể đếm số lần xuất hiện trong một sự hiểu biết danh sách, chuyển đổi chúng sang một tuple để bạn có thể băm & áp dụng tính duy nhất:

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) 

kết quả:

{(1, 2, 4, 6, 10)} 

Đủ đơn giản, nhưng rất nhiều vòng lặp dưới mui xe do các cuộc gọi lặp lại đến count. Có một cách khác, trong đó bao gồm băm nhưng có một độ phức tạp thấp hơn sẽ được sử dụng 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) 

Kết quả:

[(1, 2, 4, 6, 10)] 

(Chỉ cần đếm số các danh sách con tuple-chuyển đổi - sửa chữa các vấn đề băm -, và tạo danh sách dup bằng cách sử dụng danh sách hiểu, chỉ giữ các mục xuất hiện nhiều lần)

Bây giờ, nếu bạn muốn phát hiện có một số danh sách trùng lặp (không in), bạn có thể

  • chuyển đổi các danh sách liệt kê một danh sách các hàng để bạn có thể băm chúng trong một tập
  • so sánh độ dài của danh sách vs chiều dài của bộ:

len là khác nhau nếu có là một số bản sao:

routes_tuple = [tuple(x) for x in routes]  
print(len(routes_tuple)!=len(set(routes_tuple))) 

hay, có thể sử dụng map bằng Python 3 là đủ hiếm để được mentionned vậy:

print(len(set(map(tuple,routes))) != len(routes)) 
+1

nitpick: loại bỏ '[]' s từ bên trong 'set()' để sử dụng một biểu thức máy phát nhanh hơn – Harvey

+0

chắc chắn không phải là một nitpick !! Tôi đã quen với '" ".join ([])' để _speed up_ 'join' ... –

+0

@Donald: cũng vậy, nếu khao khát chỉ để loại bỏ các bản sao, thì đây chỉ là:' set (tuple (x)) cho x trong các tuyến đường) ' – 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

bạn sẽ nhận được thông báo hai lần. –

+0

@ Jean-FrançoisFabre ahh, bạn nói đúng, hãy để tôi sửa lỗi đó. Cảm ơn bạn đã chỉ ra rằng –

+0

@ Jean-FrançoisFabre haha ​​vâng, như một thực tế nó không phải là điều thông minh nhất để làm, tuy nhiên, trong một danh sách giảm như thế này không có nhiều điều có thể đi sai với nó. –

0
for x in routes: 

    print x, routes.count(x) 

rằng sẽ trả lại cho bạn mỗi danh sách và bao nhiêu lần nó xuất hiện. thay thế bạn chỉ có thể hiển thị nếu chúng xuất hiện> 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) 

hy vọng điều đó sẽ hữu ích!

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 

Tận hưởng!

2

Không chắc chắn nếu bạn muốn có một thư viện bên ngoài nhưng tôi có một có chứa một hàm một cách rõ ràng làm cho mục đích này: 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]] 

Lưu ý rằng điều này cũng hoạt động mà không key=tuple nhưng điều đó sẽ có O(n*n) hành vi thay vì O(n) .

>>> list(duplicates(my_list)) 
[[1, 2, 4, 6, 10]] 

Nó cũng giữ thứ tự xuất hiện (có hoặc không có key) nếu đó là quan trọng:

>>> list(duplicates([[1], [2], [3], [1], [2], [3]])) 
[[1], [2], [3]] 

Nếu bạn chỉ quan tâm nếu có bản sao bạn có thể sử dụng any trên nó thay vì list:

>>> any(duplicates([[1], [2], [3], [1], [2], [3]])) 
True 
>>> any(duplicates([[1], [2], [3]])) 
False 
Các vấn đề liên quan