Zanurkuj w Pythonie/Operatory and i or

Operatory and i or

edytuj

Operatory and i or odpowiadają boolowskim operacjom logicznym, jednak nie zwracają one wartości logicznych. Zamiast tego zwracają którąś z podanych wartości.

Przykład. Poznajemy and
>>> 'a' and 'b'           #(1)
'b'
>>> '' and 'b'            #(2)
''
>>> 'a' and 'b' and 'c'   #(3)
'c'
  1. Podczas używania and wartości są oceniane od lewej do prawej. 0, '', [], (), {} i None 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 nauczymy się w rozdziale "Obiekty i klasy". Jeśli wszystkie wartości są prawdą w kontekście logicznym, and zwraca ostatnią wartość. W tym przypadku and najpierw bierze 'a', co jest prawdą, a potem 'b', co też jest prawdą, więc zwraca ostatnią wartość, czyli 'b'.
  2. Jeśli jakaś wartość jest fałszywa w kontekście logicznym, and zwraca pierwszą fałszywą wartość. W tym wypadku '' jest pierwszą fałszywą wartością.
  3. Wszystkie wartości są prawdą, tak więc and zwraca ostatnią wartość, 'c'.
Przykład. Poznajemy or
>>> 'a' or 'b'          #(1)
'a'
>>> '' or 'b'           #(2)
'b'
>>> '' or [] or {}      #(3)
{}
>>> def sidefx():
...     print "in sidefx()"
...     return 1
>>> 'a' or sidefx()     #(4)
'a'
  1. Używając or wartości są oceniane od lewej do prawej, podobnie jak w and. Jeśli jakaś wartość jest prawdą, or zwraca tą wartość natychmiast. W tym wypadku, 'a' jest pierwszą wartością prawdziwą.
  2. or wyznacza '' jako fałsz, ale potem 'b', jako prawdę i zwraca 'b'.
  3. Jeśli wszystkie wartości są fałszem, or zwraca ostatnią wartość. or ocenia '' jako fałsz, potem [] jako fałsz, potem {} jako fałsz i zwraca {}.
  4. Zauważmy, że or 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 sidefx nigdy nie jest wywołana, ponieważ już 'a' jest prawdą i 'a' zostanie zwrócone natychmiastowo.

Jeśli jesteś osobą programującą w języku C, na pewno znajome jest ci wyrażenie bool ? a : b, z którego otrzymamy a, jeśli bool jest prawdą, lub b w przeciwnym wypadku. Dzięki sposobowi działania operatorów and i or w Pythonie, możemy osiągnąć podobny efekt.

Sztuczka and-or

edytuj
Przykład. Poznajemy sztuczkę and-or
>>> a = "first"
>>> b = "second"
>>> 1 and a or b     #(1)
'first'
>>> 0 and a or b     #(2)
'second'
  1. Ta składnia wygląda podobnie do wyrażenia bool ? a : b w C. Całe wyrażenie jest oceniane od lewej do prawej, tak więc najpierw określony zostanie and. Czyli 1 and 'first' daje 'first', potem 'first' or 'second' daje 'first'.
  2. 0 and 'first' daje 0, a potem 0 or 'second' daje 'second'.

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 Pythonową sztuczką and-or, a składnią bool ? a : b w C. Jeśli wartość a 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. Kiedy zawodzi sztuczka and-or
>>> a = ""
>>> b = "second"
>>> 1 and a or b         #(1)
'second'
  1. Ponieważ a jest pustym napisem, który Python uważa za fałsz w kontekście logicznym, więc 1 and '' daje '', a następnie '' or 'second' daje 'second'. Ups! To nie to, czego oczekiwaliśmy.

Sztuczka and-or, czyli wyrażenie bool and a or b, nie będzie działało w identyczny sposób, jak wyrażenie w C bool ? a : b, jeśli a będzie fałszem w kontekście logicznym.

Prawdziwą sztuczką kryjącą się za sztuczką and-or, jest upewnienie się, czy wartość a nigdy nie jest fałszywa. Jednym ze sposobów na wykonanie tego to przekształcenie a w [a] i b w [b], a potem pobranie pierwszego elementu ze zwróconej listy, którym będzie a lub b.

Przykład. Bezpieczne użycie sztuczki and-or
>>> a = ""
>>> b = "second"
>>> (1 and [a] or [b])[0] #(1)
''
  1. Jako że [a] jest niepustą listą, więc nigdy nie będzie fałszem (tylko pusta lista jest fałszem). Nawet gdy a jest równe 0 lub '' lub inną wartością dającą fałsz, lista [a] bę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ą if, 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 i tak czasami korzystać z tej sztuczki. Na przykład, są pewne przypadki w Pythonie gdzie instrukcje if nie są dozwolone np. w wyrażeniach lambda.

Materiały dodatkowe

edytuj