Mam dwóch list:Znajdź liczbę 1s w tej samej pozycji w dwóch tablicach
A = [0,0,0,1,0,1]
B = [0,0,1,1,1,1]
Chcę znaleźć liczbę 1s w tej samej pozycji w obu listach.
Odpowiedź na tych tablicach byłaby 2.
Mam dwóch list:Znajdź liczbę 1s w tej samej pozycji w dwóch tablicach
A = [0,0,0,1,0,1]
B = [0,0,1,1,1,1]
Chcę znaleźć liczbę 1s w tej samej pozycji w obu listach.
Odpowiedź na tych tablicach byłaby 2.
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?
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
Świetna odpowiedź. Ponieważ python pozwala operatorom porównywać łańcuchy, możesz mieć (a == b == 1) dla if. –
Dzięki, zaktualizowany – Drakosha
nie potrzebujesz nawiasów wokół porównania – SilentGhost
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.)
Fajny pomysł, jednak jest to O (NlogN) przeciwieństwie do mojego rozwiązania O (N). Będziesz musiał dostarczyć wersję prewersyjną i szybką;) – Drakosha
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
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
Miło, ale powinieneś powiedzieć, że dotyczy to wyłącznie elementów ∈ {0, 1}. Wiem, że to jest specyfikacja, ale EIBTI :) – tzot
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.
9,5 nas vs 2.1 nas nie jest dokładnie "cierpieniem wydajności". – SilentGhost
Zobacz dodane informacje o porównaniach długości tablicy ... –
[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.
"Czy byłoby to możliwe w twoim języku?" Tak. :) – tzot
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
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