2011-01-23 50 views
5
a = [1, 2, 9, 5, 1] 
b = [9, 8, 7, 6, 5] 

Tôi muốn đếm số lượng trùng lặp giữa hai danh sách. Vì vậy, bằng cách sử dụng ở trên, tôi muốn trả về một số 2 vì 9 và 5 là phổ biến cho cả hai danh sách.Đếm trùng lặp giữa 2 danh sách

Tôi đã thử một cái gì đó như thế này nhưng nó không hoàn toàn hoạt động.

def filter_(x, y): 
    count = 0 
    for num in y: 
     if num in x: 
      count += 1 
      return count 
+0

Lưu ý rằng khi nó hoạt động (trừ 'return' hai lần), nó có phức tạp' O (n * m) ', tức là quy mô khá khủng khiếp. – delnan

+0

@delnan cảm ơn mẹo. do đó, sử dụng quy mô giao lộ tốt hơn. – super9

+0

Có. Bạn thực sự có thể làm tốt hơn, nhưng điều đó đòi hỏi nhiều hơn một dòng mã (ý tưởng là bạn chỉ cần một bộ danh sách đầu tiên, sau đó lặp lại lần thứ hai và giữ các mục nằm trong tập hợp - tiết kiệm tạo một giây bộ). – delnan

Trả lời

16

ngắn hơn chiều và tốt hơn:

>>> a = [1, 2, 9, 5, 1] 
>>> b = [9, 8, 7, 6, 5] 
>>> len(set(a) & set(b))  # & is intersection - elements common to both 
2 

Tại sao mã của bạn không hoạt động:

>>> def filter_(x, y): 
...  count = 0 
...  for num in y: 
...    if num in x: 
...      count += 1 
...  return count 
... 
>>> filter_(a, b) 
2 

bạn return count là bên trong vòng lặp for và nó trở lại mà không cần thực hiện là hoàn tất.

+0

Chúa ơi, tôi tiếp tục mắc sai lầm tương tự. Cảm ơn! – super9

8

Bạn có thể sử dụng set.intersection:

>>> set(a).intersection(set(b)) # or just: set(a).intersection(b) 
set([9, 5]) 

Hoặc, đối với chiều dài của giao lộ:

>>> len(set(a).intersection(set(b))) 
2 

Hoặc, ngắn gọn hơn:

>>> len(set(a) & set(b)) 
2 
+0

Tôi không muốn 9,5. Tôi muốn đếm số 2. – super9

+0

Không nhất thiết phải đặt một cách rõ ràng từ danh sách b, phương thức giao nhau đã đặt hỗ trợ danh sách làm đầu vào. – Spaceghost

3

Chuyển đổi họ set s và đếm giao lộ.

len(set(a).intersection(set(b))) 
4

Nếu bạn muốn đếm các mục nhập đa mục tiêu, các giải pháp dựa trên tập hợp sẽ không thành công; bạn sẽ cần một cái gì đó giống như

from collections import Counter 

def numDups(a, b): 
    if len(a)>len(b): 
     a,b = b,a 

    a_count = Counter(a) 
    b_count = Counter(b) 

    return sum(min(b_count[ak], av) for ak,av in a_count.iteritems()) 

sau đó

numDups([1,1,2,3], [1,1,1,1,1]) 

lợi nhuận 2. Thời gian chạy trên quy mô này là O (n + m).

Ngoài ra, giải pháp ban đầu của bạn

for num in y: 
    if num in x: 
     count += 1 

là sai - áp dụng cho [1,2,3,3] và [1,1,1,1,1,3], mã của bạn sẽ trở lại một trong hai 3 hoặc 6, không phải trong số đó là chính xác (câu trả lời phải là 2).

+0

giải pháp này là tốt hơn bởi vì nó đếm các bản sao quá, cảm ơn :) – Zavael

Các vấn đề liên quan