Zanurkuj w Pythonie/Operatory and i or: Różnice pomiędzy wersjami

Usunięta treść Dodana treść
zamiana ProstaNawigacja->Subst:ProstaNawigacja
Piotr (dyskusja | edycje)
mNie podano opisu zmian
Linia 1:
== Operatory <ttcode>and</ttcode> i <ttcode>or</ttcode> ==
{{Podświetl|py}}
== Operatory <tt>and</tt> i <tt>or</tt> ==
 
Operatory <ttcode>and</ttcode> i <ttcode>or</ttcode> odpowiadają boolowskim operacjom logicznym, jednak nie zwracają one wartości logicznych. Zamiast tego zwracają, którąś z podanych wartości.
 
'''Przykład 4.15. Poznajemy <tt>and</tt>'''
 
{{Python/Przykład
'''Przykład |4.15. |Poznajemy <ttcode>and</ttcode>'''
|tekst=
>>> 'a' and 'b' #(1)
{{samp|'b'}}
>>> <nowiki>''</nowiki> and 'b' #(2)</nowiki>
{{samp|<nowiki>''</nowiki>}}
>>> 'a' and 'b' and 'c' #(3)
{{samp|'c'}}
 
# Podczas używania <ttcode>and</ttcode>, wartości są oceniane od lewej do prawej w kontekście logicznym. <ttcode>0</ttcode>, <ttcode><nowiki>''</nowiki></ttcode>, <ttcode>[]</ttcode>, <ttcode>()</ttcode>, <ttcode>{}</ttcode> i <ttcode>None</ttcode> są fałszem w kontekście logicznym, natomiast wszystko inne jest prawdą. Cóż, prawie wszystko. Domyślnie instancje klasy w kontekście logicznym są prawdą, ale możesz zdefiniować specjalne metody w swojej klasie, które sprawią, że będzie ona fałszem w kontekście logicznym. Wszystkiego o klasach i specjalnych metodach nauczysznauczymy się w rozdziale [[../Obiekty i klasy|Obiekty i klasy/]]. Jeśli wszystkie wartości są prawdą w kontekście logicznym, <ttcode>and</ttcode> zwraca ostatnią wartość. W tym przypadku <code>and</code> najpierw wyliczabierze <ttcode>'a'</ttcode>, co jest prawdą, a potem <ttcode>'b'</ttcode>, co też jest prawdą, iwięc zwraca ostatnią wartość, czyli <ttcode>'b'</ttcode>.
# Jeśli jakaś wartość jest fałszywa w kontekście logicznym, <ttcode>and</ttcode> zwraca pierwszą fałszywą wartość. W tym wypadku <ttcode><nowiki>''</nowiki></ttcode> jest pierwszą fałszywą wartością.
# Wszystkie wartości są prawdą, tak więc <ttcode>and</ttcode> zwraca ostatnią wartość, <ttcode>'c'</ttcode>.
}}
 
'''Przykład 4.16. Poznajemy <tt>or</tt>'''
 
{{Python/Przykład
'''Przykład |4.16. |Poznajemy <ttcode>or</ttcode>'''
|tekst=
>>> 'a' or 'b' #(1)
{{samp|'a'}}
>>> <nowiki>''</nowiki> or 'b'</nowiki> #(2)
{{samp|'b'}}
>>> <nowiki>''</nowiki> or [] or {} #(3)
{}
Linia 29 ⟶ 31:
... return 1
>>> 'a' or sidefx() #(4)
{{samp|'a'}}
 
# Używając <ttcode>or</ttcode>, wartości są wyliczane w kontekście logicznym od lewej do prawej, tak jak <ttcode>and</ttcode>. Jeśli jakaś wartość jest prawdą, <code>or</code> zwraca tą wartość natychmiast. W tym wypadku, <ttcode>'a'</ttcode> jest pierwszą wartością prawdziwą.
# <ttcode>or</ttcode> wyliczawyznacza <ttcode><nowiki>''</nowiki></ttcode> jako fałsz, ale potem <ttcode>'b'</ttcode>, jako prawda,prawdę i zwraca <ttcode>'b'</ttcode>.
# Jeśli wszystkie wartości są fałszem, <ttcode>or</ttcode> zwraca ostatnią wartość. <ttcode>or</ttcode> ocenia <ttcode><nowiki>''</nowiki></ttcode> jako fałsz, potem <ttcode>[]</ttcode> jako fałsz, potem <ttcode>{}</ttcode> jako fałsz i zwraca <ttcode>{}</ttcode>.
# ZauważZauważmy, że <ttcode>or</ttcode> ocenia kolejne wartości od lewej do prawej, dopóki nie znajdzie takiej, która jest prawdą w kontekście logicznym, a pozostałą resztę ignoruje. Tutaj, funkcja <ttcode>sidefx</ttcode> nigdy nie jest wywołana, ponieważ już <ttcode>'a'</ttcode> jest prawdą i <ttcode>'a'</ttcode> zostanie zwrócone natychmiastowo.
}}
 
Jeśli jesteś osobą programującą w języku [[C]], na pewno znajome jest ci wyrażenie <ttcode class="lang-c">bool ? a : b</ttcode>, z którego otrzymamy <ttcode class="lang-c">a</ttcode> jeśli <ttcode class="lang-c">bool</ttcode> jest prawdą lub <ttcode class="lang-c">b</ttcode> w przeciwnym wypadku. Dzięki sposobowi działania operatorów <ttcode>and</ttcode> i <ttcode>or</ttcode> w Pythonie, możemy osiągnąć podobny efekt.
 
==== Używanie sztuczkiSztuczka <ttcode>and</ttcode>-<ttcode>or</ttcode> ====
 
'''Przykład 4.17. Poznajemy sztuczkę and-or'''
 
{{Python/Przykład
'''Przykład |4.17. |Poznajemy sztuczkę <code>and</code>-<code>or'''</code>
|tekst=
>>> a = "first"
>>> b = "second"
>>> 1 and a or b #(1)
{{samp|'first'}}
>>> 0 and a or b #(2)
{{samp|'second'}}
 
# Ta składnia wygląda podobnie do wyrażenia <ttcode class="lang-c">bool ? a : b</ttcode> w [[C]]. Całe wyrażenie jest oceniane od lewej do prawej, tak więc najpierw określony zostanie <ttcode>and</ttcode>. Czyli <ttcode>1 and 'first'</ttcode> daje <ttcode>'first'</ttcode>, potem <ttcode>'first' or 'second'</ttcode> daje <ttcode>'first'</ttcode>.
# <ttcode>0 and 'first'</ttcode> daje <ttcode>0</ttcode>, a potem <ttcode>0 or 'second'</ttcode> daje <tt>'second'</tt>.
}}
 
Jakkolwiek te wyrażenia Pythona są po prostu logiką boolowską, a nie specjalną konstrukcją języka, istnieje jedna bardzo ważna różnica pomiędzy tą sztuczką <tt>and</tt>-<tt>or</tt> w Pythonie a składnią <tt class="lang-c">bool ? a : b</tt> w C. Jeśli wartość <tt>a</tt> jest fałszem, wyrażenie to nie będzie działało tak, jakbyśmy chcieli. Można się na tym nieźle przejechać, co zobaczymy w poniższym przykładzie.
 
Jakkolwiek te wyrażenia Pythona są po prostu logiką boolowską, a nie specjalną konstrukcją języka,. istniejeIstnieje jedna bardzo ważna różnica pomiędzy Pythonową sztuczką <ttcode>and</ttcode>-<ttcode>or</ttcode> w Pythonie, a składnią <ttcode class="lang-c">bool ? a : b</ttcode> w C. Jeśli wartość <ttcode>a</ttcode> jest fałszem, wyrażenie to nie będzie działało tak, jakbyśmy chcieli. Można się na tym nieźle przejechać, co zobaczymy w poniższym przykładzie.
'''Przykład 4.18. Kiedy zawodzi sztuczka <tt>and</tt>-<tt>or</tt>'''
 
{{Python/Przykład
'''Przykład |4.18. |Kiedy zawodzi sztuczka <ttcode>and</ttcode>-<ttcode>or</ttcode>'''
|tekst=
>>> a = ""
>>> b = "second"
>>> 1 and a or b #(1)
{{samp|'second'}}
# Jako żePonieważ <ttcode>a</ttcode> jest pustym napisem, który Python uważa za fałsz w kontekście logicznym, więc <ttcode>1 and <nowiki>''</nowiki></ttcode> daje <ttcode><nowiki>''</nowiki></ttcode>, a następnie <ttcode><nowiki>''</nowiki> or 'second'</ttcode> daje <ttcode>'second'</ttcode>. Ups! To nie to, czego chcieliśmyoczekiwaliśmy.
 
}}
# Jako że <tt>a</tt> jest pustym napisem, który Python uważa za fałsz w kontekście logicznym, <tt>1 and <nowiki>''</nowiki></tt> daje <tt><nowiki>''</nowiki></tt>, następnie <tt><nowiki>''</nowiki> or 'second'</tt> daje <tt>'second'</tt>. Ups! To nie to, czego chcieliśmy.
 
Sztuczka <ttcode>and</ttcode>-<ttcode>or</ttcode>, czyli wyrażenie <ttcode>bool and a or b</ttcode>, nie będzie działało w identyczny sposób jak wyrażenie w C <ttcode class="lang-c">bool ? a : b</ttcode>, gdyjeśli <ttcode>a</ttcode> jestbędzie fałszem w kontekście logicznym.
 
Prawdziwą sztuczką kryjącą się za sztuczką <ttcode>and</ttcode>-<ttcode>or</ttcode>, jest upewnienie się, żeczy wartość <ttcode>a</ttcode> nigdy nie jest fałszywa. Jednym ze sposobów na wykonanie tego to przekształcenie <ttcode>a</ttcode> w <ttcode>[a]</ttcode> i <ttcode>b</ttcode> w <ttcode>[b]</ttcode>, a potem pobranie pierwszego elementu ze zwróconej listy, którym będzie <ttcode>a</ttcode> lub <ttcode>b</ttcode>.
 
'''{{Python/Przykład
|4.19. |Bezpieczne użycie sztuczki <ttcode>and</ttcode>-<ttcode>or</ttcode>
|tekst=
>>> a = ""
>>> b = "second"
Linia 73 ⟶ 81:
<nowiki>''</nowiki>
 
# Jako że <ttcode>[a]</ttcode> jest nie pustą listą, więc nigdy nie dajebędzie fałszem (tylko pusta lista jest fałszufałszem). Nawet gdy <ttcode>a</ttcode> jest równe <ttcode>0</ttcode> lub <ttcode><nowiki>''</nowiki></ttcode> lub inną wartością dającą fałsz, lista <tt>[a]</tt> jestbędzie prawdą, ponieważ ma jeden element.
}}
 
Jak dotąd, ta sztuczka może wydawać się bardziej uciążliwa niż pomocna. Możesz przecież osiągnąć to samo zachowanie instrukcją <ttcode>if</ttcode>, więc po co to całe zamieszanie. Cóż, w wielu przypadkach, wybierasz pomiędzy dwoma stałymi wartościami, więc możesz użyć prostszego zapisu i się nie martwić, ponieważ wiesz, że wartość zawsze będzie prawdą. I nawet kiedy potrzebujesz użyć bardziej skomplikowanej, bezpiecznej formy, istnieją powody aby tak robić. Na przykład, są pewne przypadki w Pythonie gdzie instrukcje <ttcode>if</ttcode> nie są dozwolone, tak jaknp. w funkcjachwyrażeniach <ttcode>lambda</ttcode>.
 
===== Materiały dodatkowe =====
* [http://www.activestate.com/ASPN/Python/Cookbook/ Python Cookbook] omawia [http://www.activestate.com/ASPN/Python/Cookbook/Recipe/52310 alternatywy do triku <ttcode>and</ttcode>-<ttcode>or</ttcode>].
 
<noinclude>
{{Nawigacja|Python|
[[Python../Filtrowanie listy|Filtrowanie listy/]]|
[[Python../Wyrażenia lambda|Wyrażenia <code>lambda</code>]]|
}}
{{Podświetl|py}}
</noinclude>