2009-05-18 3 views

Trả lời

1

Tôi không phải là chuyên gia về Python, nhưng điều gì sai với vòng lặp đơn giản từ đầu đến cuối mảng đầu tiên?

Trong C# tôi sẽ làm một cái gì đó như:

int match=0; 

for (int cnt=0; cnt< A.Count;cnt++) 
{ 
    if ((A[cnt]==B[cnt]==1)) match++; 
} 

rằng có thể trong ngôn ngữ của bạn?

+0

"Điều đó có thể thực hiện được bằng ngôn ngữ của bạn không?" Vâng. :) – tzot

+0

Có thể, có, nhưng không thành ngữ. Hơi nhanh hơn cho các danh sách dài, có vẻ như vậy. Đối với hai danh sách ngẫu nhiên có độ dài 10'000, giải pháp của bạn (dịch sang python) mất 0,003s trên hệ thống của tôi, trong khi 'drakosha' mất 0,005 và 'bendin' mất 0,020 giây. – bendin

+0

Tuy nhiên, đối với các yếu tố 1'000'000: berggreendk = 0,031s, bendin = 0,045, drakosha = 1,02s có thể không chứng minh được điều gì khác ngoài thực tế là việc đo điểm chuẩn vi mô khó thực hiện đúng. – bendin

19

Một chút ngắn hơn và hy vọng pythonic hơn cách:

>>> A=[0,0,0,1,0,1] 
>>> B=[0,0,1,1,1,1] 

x = sum(1 for a,b in zip(A,B) if (a==b==1)) 
>>> x 
2 
+6

Câu trả lời hay. Như python cho phép bạn chuỗi các toán tử so sánh, bạn có thể có (a == b == 1) cho if. –

+0

Cảm ơn, cập nhật – Drakosha

+0

bạn không cần ngoặc đơn xung quanh so sánh – SilentGhost

1

Thúc đẩy bởi nhu cầu ngắn gọn là ngoan cố, tôi cung cấp các giải pháp sau đây:

A = [0,0,0,1,0,1] 
B = [0,0,1,1,1,1] 

print len(set(i for i, n in enumerate(A) if n == 1) & 
      set(i for i, n in enumerate(B) if n == 1)) 

(gợi ý Drakosha là một cách xa hợp lý hơn để giải quyết vấn đề này. Điều này chỉ chứng minh rằng người ta thường có thể xem xét cùng một vấn đề theo những cách khác nhau.)

+0

Ý tưởng hay, tuy nhiên đó là O (NlogN) trái ngược với giải pháp O (N) của tôi. Bạn sẽ cần phải cung cấp phiên bản trước và nhanh;) – Drakosha

0

Với SciPy:

>>> from scipy import array 
>>> A=array([0,0,0,1,0,1]) 
>>> B=array([0,0,1,1,1,1]) 

>>> A==B 
array([ True, True, False, True, False, True], dtype=bool) 
>>> sum(A==B) 
4 

>>> A!=B 
array([False, False, True, False, True, False], dtype=bool) 
>>> sum(A!=B) 
2 
2

Hơi ngắn biến thể của Drakosha của:

>>> A = [0,0,0,1,0,1] 
>>> B = [0,0,1,1,1,1] 
>>> sum(a*b for a, b in zip(A, B)) 
2 
+0

Rất hay, nhưng bạn nên nhận xét rằng điều này áp dụng đúng cho các phần tử ∈ {0, 1}. Tôi biết rằng đây là đặc điểm kỹ thuật, nhưng EIBTI :) – tzot

0

Ở đây có một phương pháp mà khai thác thực tế là mảng chỉ chứa số không và những người thân.

Sản phẩm vô hướng của hai vectơ x và y là tổng (x (i) * y (i)) tình huống duy nhất cho kết quả khác 0 nếu x (i) == y (i) == 1 do đó sử dụng numpy ví dụ

from numpy import * 
x = array([0,0,0,1,0,1]) 
y = array([0,0,1,1,1,1]) 
print dot(x,y) 

đơn giản và đẹp mắt. Phương pháp này n nhân và thêm n-1 lần, tuy nhiên có các triển khai nhanh bằng SSE, GPGPU, vectơ, (thêm từ ưa thích của bạn ở đây) cho các sản phẩm chấm (sản phẩm vô hướng)

Tôi đã định thời phương pháp:

sum(1 for a,b in zip(x,y) if (a==b==1)) 

và thấy rằng đối với 1000000 loops các numPy phiên bản đã làm nó trong 2121ms và zip-method đã làm nó trong 9502ms do đó numPy phiên bản là nhanh hơn rất nhiều

tôi đã làm một phân tích tốt hơn của efectivness và thấy rằng cho n phần tử (s) trong mảng các phương pháp zip mất t1 ms và dấu chấm produ ct mất ms t2 cho một itteration

 
elements  zip  dot 
1   0.0030 0.0207 
10   0.0063 0.0230 
100  0.0393 0.0476 
1000  0.3696 0.2932 
10000  7.6144 2.7781 
100000 115.8824 30.1305 

Từ dữ liệu này người ta có thể rút ra kết luận rằng nếu số phần tử trong mảng dự kiến ​​(trong bình) có hơn 350 (hoặc nói 1000) ta nên xem xét để sử dụng phương pháp dot-product thay thế.

+1

9.5 chúng tôi so với 2.1 chúng tôi không chính xác là "hiệu suất đau khổ". – SilentGhost

+0

Xem thông tin bổ sung về so sánh độ dài mảng ... –

0
[A[i]+B[i] for i in range(min([len(A), len(B)]))].count(2) 

Về cơ bản, điều này chỉ tạo danh sách mới có tất cả các thành phần của hai yếu tố khác được thêm vào với nhau. Bạn biết có hai số 1 nếu tổng là 2 (giả sử chỉ 0 và 1 trong danh sách). Do đó, chỉ cần thực hiện thao tác đếm trên 2.