Сравнения и логика
Представьте контролёра у входа в кинозал на фильм «18+». Он задаёт вопросы, на которые отвечают «да» или «нет»: есть ли билет, исполнилось ли зрителю 18. Пускает он, только когда оба ответа — «да».
Программе постоянно нужны такие же ответы: совершеннолетний ли пользователь, попадает ли число в диапазон. Такой ответ даёт сравнение, и его результат имеет тип bool:
age = 20
adult = age >= 18
teen = 13 <= age <= 19
print(adult, teen) # True False
print(age == 20, age != 20) # True FalseДавайте разберём программу по строкам:
adult = age >= 18кладёт вadultответ на вопрос «двадцать не меньше восемнадцати?» —True.teen = 13 <= age <= 19проверяет, попадает лиageв диапазон от 13 до 19. Двадцать не попадает, поэтомуteenравнаFalse.- Последняя строка печатает
True False:ageравна20, значит, «не равна 20» неверно.
Сравнения
Операторов сравнения шесть:
==— равно;!=— не равно;<и<=— меньше, меньше или равно;>и>=— больше, больше или равно.
Двойной знак == проверяет равенство, а одиночный = присваивает значение. int и float сравниваются по величине: 1 == 1.0 даёт True. Строка никогда не равна числу: "5" == 5 даёт False.
Сравнения можно сцеплять, как в математике. Цепочка сравнений 13 <= age <= 19 значит «13 <= age, и при этом age <= 19». Сравнения выполняются после арифметики: n % 2 == 0 значит (n % 2) == 0.
and, or и not
Логические операторы соединяют условия, как контролёр соединяет свои вопросы. Их три.
and
a and b верно, когда верны оба операнда. Так контролёр пускает в зал: билет есть, и зрителю есть 18.
or
a or b верно, когда верен хотя бы один операнд. Так кассир даёт скидку: зритель — студент или пенсионер.
not
not a меняет True на False и обратно. Первым выполняется not, затем and, последним — or.
Короткая схема
Контролёр, увидев, что билета нет, про возраст уже не спрашивает: ответ ясен. Python поступает так же. and и or вычисляют левый операнд первым, и если по нему ответ уже ясен, правый не вычисляется вовсе.
Для and это ложный левый операнд, для or — истинный. Такое правило называют вычислением по короткой схеме:
def is_positive(n):
print("check", n, end=" ")
return n > 0
print(is_positive(-1) and is_positive(5)) # check -1 False
print(is_positive(5) or is_positive(-1)) # check 5 TrueРазберём, что напечаталось:
is_positive(-1)печатаетcheck -1и возвращаетFalse.- Левый операнд
andложен, поэтомуis_positive(5)не вызывается, иprintвыводитFalse. - Во второй строке
is_positive(5)возвращаетTrue, иorуже не вызываетis_positive(-1).
В каждой строке функция вызвана один раз: правый операнд не понадобился.
Что возвращают and и or
Здесь аналогия с контролёром заканчивается. Контролёр отвечает только «да» или «нет», а and и or в Python возвращают один из своих операндов.
Операндом and и or может быть не только bool. Тогда ноль и пустая строка "" считаются ложными, а другие числа и непустые строки — истинными. Результат — тот операнд, на котором вычисление остановилось:
print(0 or 7, "" or "guest", 5 or 7) # 7 guest 5
print(0 and 7, 5 and 7) # 0 7
print(not 5, not "") # False TrueПравила такие:
orвозвращает первый истинный операнд, а если таких нет — последний;andвозвращает первый ложный операнд, а если все истинны — последний;notвсегда возвращаетTrueилиFalse.
Поэтому "" or "guest" даёт guest: так подставляют значение по умолчанию вместо пустой строки. Этот вопрос часто задают на собеседовании: «Что вернёт 0 or 7?» Правильный ответ — 7, а не True.
Частая ошибка
Проверку «ответ равен 1 или 2» записывают так, как её произносят:
answer = 3
is_valid = answer == 1 or 2 # ✗
print(is_valid) # 2Ошибки Python не сообщает. Выражение читается как (answer == 1) or 2: левая часть дала False, и or вернул правый операнд 2. Сравнение нужно в каждой части: answer == 1 or answer == 2 даёт False.
Главное
- Сравнение даёт
bool;==проверяет равенство, а=присваивает. andиorне вычисляют правый операнд, если ответ ясен по левому.orвозвращает первый истинный операнд,and— первый ложный; если такого нет, оба возвращают последний.
Подпишись, чтобы пройти курс
Курс бесплатный. Войди через Telegram и подпишись на канал — откроются все уроки.