2009-05-18 18 views

Odpowiedz

1

Nie jestem ekspertem od Pythona, ale to, co jest nie tak z prostej pętli od początku do końca pierwszej tablicy?

W języku C# Chciałbym zrobić coś takiego:

int match=0; 

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

byłoby to możliwe w Twoim języku?

+0

"Czy byłoby to możliwe w twoim języku?" Tak. :) – tzot

+0

Możliwe, tak, ale nie idiomatyczne. Wydaje się, że jest nieco szybszy w przypadku długich list. Dla dwóch losowych list o długości 10 000, twoje rozwiązanie (przetłumaczone na pythona) zajęło w moim systemie 0,003, podczas gdy "drakosha" zajęło 0,005, a "bendin" 0,020s. – bendin

+0

Jeszcze dziwniejszy, dla 1 000 000 elementów: berggreendk = 0,031s, bendin = 0,045, drakosha = 1,02 s, co prawdopodobnie nie dowodzi niczego innego niż fakt, że mikro-benchmarking jest trudny do wykonania. – bendin

19

Nieco krótszy i mamy nadzieję, bardziej pythonic sposób:

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

Świetna odpowiedź. Ponieważ python pozwala operatorom porównywać łańcuchy, możesz mieć (a == b == 1) dla if. –

+0

Dzięki, zaktualizowany – Drakosha

+0

nie potrzebujesz nawiasów wokół porównania – SilentGhost

1

Zmotywowany przez krótki konieczności być przewrotny, oferuję następujące rozwiązanie:

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

(sugestia Drakosha jest znacznie bardziej rozsądny sposób To po prostu pokazuje, że często można spojrzeć na ten sam problem na różne sposoby.)

+0

Fajny pomysł, jednak jest to O (NlogN) przeciwieństwie do mojego rozwiązania O (N). Będziesz musiał dostarczyć wersję prewersyjną i szybką;) – Drakosha

0

Z 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

Nieco krótsza odmiana Drakosha użytkownika:

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

Miło, ale powinieneś powiedzieć, że dotyczy to wyłącznie elementów ∈ {0, 1}. Wiem, że to jest specyfikacja, ale EIBTI :) – tzot

0

Nadchodzi inną metodę, która wykorzystuje fakt, że tablica zawiera tylko zer i jedynek.

Iloczyn skalarny dwóch wektorów x i y jest sumą (x (i) * y (i)) jedyną sytuacją, która daje wynik niezerowy jest jeśli x (i) == y (i) == 1 tak używając numpy na przykład

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

prosty i miły. Ta metoda wykonuje n multiplikacji i dodaje n-1 razy, jednak istnieją szybkie implementacje za pomocą SSE, GPGPU, wektoryzacji (dodaj tutaj swoje wymyślne słowo) dla produktów z kropkami (produktów skalarnych)

Wyzerowałem metodę numpy metoda:

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

i okazało się, że za 1000000 zapętla numpy wersja zrobił to w 2121ms i zip-metoda zrobił to w 9502ms zatem numpy-wersja jest dużo szybsza

zrobiłem lepszą analizę efekcyjności i okazało się, że dla elementu (elementów) n w tablicy metoda zip trwała t1 ms, a procesor punktowy ct wziął t2 ms dla jednego 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 

Z tych danych można wyciągnąć wniosek, że jeśli oczekuje się (w średniej) być więcej niż 350 liczba elementów w tablicy (lub powiedzieć, 1000) należy rozważyć zamiast tego używać metody dot-product.

+1

9,5 nas vs 2.1 nas nie jest dokładnie "cierpieniem wydajności". – SilentGhost

+0

Zobacz dodane informacje o porównaniach długości tablicy ... –

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

Zasadniczo po prostu tworzy nową listę, która zawiera wszystkie elementy pozostałych dwóch. Wiesz, że były dwie 1 jeśli suma wynosi 2 (zakładając tylko 0 i 1 na liście). Dlatego po prostu wykonaj operację liczenia na 2.

Powiązane problemy