O list
Najpierw bardzo ważny punkt, od którego wszystko się potoczy (mam nadzieję).
W zwykłym Pythonie list
nie jest niczym szczególnym (z wyjątkiem posiadania ładnej składni do konstruowania, co jest głównie historycznym przypadkiem). Utworzona lista [3,2,6]
jest pod każdym względem zwykłym obiektem Pythona, takim jak liczba 3
, zestaw {3,7}
lub funkcja lambda x: x+5
.
(Tak, obsługuje zmianę swoich elementów, obsługuje iterację i wiele innych rzeczy, ale tym właśnie jest typ: obsługuje niektóre operacje, podczas gdy inne nie obsługuje. Int obsługuje podnoszenie do potęgi, ale to nie jest uczyń go wyjątkowym - po prostu tym jest int. lambda obsługuje wywoływanie, ale to nie czyni go wyjątkowym - w końcu do tego służy lambda :).
O and
and
nie jest operatorem (możesz go nazwać „operatorem”, ale możesz też zadzwonić do operatora „for” :). Operatory w Pythonie to (zaimplementowane) metody wywoływane na obiektach pewnego typu, zwykle napisane jako część tego typu. Nie ma sposobu, aby metoda zawierała ocenę niektórych swoich operandów, ale and
może (i musi) to zrobić.
Konsekwencją tego jest to, że and
nie można go przeciążać, tak jak for
nie można przeciążać. Jest to całkowicie ogólne i komunikuje się za pomocą określonego protokołu. Co można zrobić, to dostosować część protokołu, ale to nie znaczy, można zmienić zachowanie and
całkowicie. Protokół jest następujący:
Wyobraź sobie, że Python interpretuje „a i b” (nie dzieje się to dosłownie w ten sposób, ale pomaga to zrozumieć). Jeśli chodzi o „i”, patrzy na obiekt, który właśnie ocenił (a) i pyta: czy to prawda? ( NIE : jesteś True
?) Jeśli jesteś autorem klasy a, możesz dostosować tę odpowiedź. Jeśli a
odpowie „nie” and
(całkowicie pomija b, nie jest ono w ogóle oceniane i) mówi: a
jest moim wynikiem ( NIE : Fałsz to mój wynik).
Jeśli a
nie odpowiada, and
pyta: jaka jest twoja długość? (Ponownie, możesz dostosować to jako autor a
klasy). Jeśli a
odpowiada 0, and
robi to samo, co powyżej - uważa to za fałszywe ( NIE fałszywe), pomija b i podaje a
wynik.
Jeśli a
odpowie coś innego niż 0 na drugie pytanie („jaka jest twoja długość”), lub w ogóle nie odpowie lub odpowie „tak” na pierwsze pytanie („czy jesteś prawdziwy”), and
ocenia b i mówi: b
to mój wynik. Zauważ, że NIE zadaje b
żadnych pytań.
Innym sposobem na powiedzenie tego wszystkiego jest to, że a and b
jest prawie tak samo, jak b if a else a
, z wyjątkiem tego, że a jest oceniane tylko raz.
Teraz usiądź na kilka minut z długopisem i kartką i przekonaj się, że kiedy {a, b} jest podzbiorem {Prawda, Fałsz}, to działa dokładnie tak, jak można by oczekiwać od operatorów boolowskich. Mam jednak nadzieję, że przekonałem Cię, że jest on znacznie bardziej ogólny i, jak zobaczysz, w ten sposób znacznie bardziej przydatny.
Łącząc te dwa razem
Mam nadzieję, że rozumiesz swój przykład 1. and
Nie obchodzi mnie, czy mylist1 jest liczbą, listą, lambdą czy obiektem klasy Argmhbl. Dba tylko o odpowiedź mylist1 na pytania protokołu. I oczywiście mylist1 odpowiada 5 na pytanie o długość, więc i zwraca mylist2. I to wszystko. Nie ma to nic wspólnego z elementami mylist1 i mylist2 - nigdzie nie pojawiają się na obrazku.
Drugi przykład: &
onlist
Z drugiej strony &
jest operatorem jak każdy inny, jak +
np. Można go zdefiniować dla typu, definiując specjalną metodę dla tej klasy. int
definiuje to jako bitowe „i”, a bool definiuje jako logiczne „i”, ale to tylko jedna opcja: na przykład zbiory i niektóre inne obiekty, takie jak widoki kluczy dykt, definiują to jako zestaw przecięcia. list
po prostu tego nie definiuje, prawdopodobnie dlatego, że Guido nie wymyślił żadnego oczywistego sposobu zdefiniowania tego.
tępy
Z drugiej strony: -D, tablice numpy są wyjątkowe, a przynajmniej starają się być. Oczywiście numpy.array jest tylko klasą, nie może and
w żaden sposób nadpisać , więc robi następną najlepszą rzecz: gdy zapytamy „czy jesteś prawdziwy”, numpy.array wywołuje błąd ValueError, skutecznie mówiąc „proszę przeformułować pytanie, mój pogląd na prawdę nie pasuje do twojego modelu ”. (Zwróć uwagę, że wiadomość ValueError nie mówi o tym and
- ponieważ numpy.array nie wie, kto zadaje pytanie; po prostu mówi o prawdzie).
Bo &
to zupełnie inna historia. numpy.array może zdefiniować go tak, jak chce, i definiuje &
spójnie z innymi operatorami: punktowy. Więc w końcu dostajesz to, czego chcesz.
HTH,
np.bitwise_and()
inp.logical_and()
i przyjaciele, aby uniknąć nieporozumień.