Модуль 2 · Урок 2.1
Логические выражения
Сравнения дают True или False; and, or и not собирают из них условия, а короткое вычисление защищает от ошибок.
До сих пор программа выполняла все строки подряд. Но часто действие зависит от данных: хватит ли денег, делится ли число, попадает ли балл в нужный диапазон. Чтобы программа могла выбирать, ей нужны ответы «да» или «нет». Такие ответы дают сравнения, а and, or и not собирают из простых ответов сложные. Как программа выбирает действия по ответу, разберём в следующем уроке.
Проверять условия будем на числе x = 12: чётно ли оно, делится ли на 3, лежит ли между 5 и 20.
Сравнения
Сравнение отвечает на вопрос «да» или «нет». Ответ — одно из двух значений: True («да», истина) или False («нет», ложь). Это не текст, а значения особого типа bool — того, что в уроке о типах был обещан на потом:
temperature = 18is_warm = temperature >= 15print(is_warm)print(type(is_warm))= присваивает, == сравнивает. В записи is_warm = temperature >= 15 правая часть отвечает на вопрос, а = связывает имя с ответом. Всего сравнений шесть:
x = 12print(x == 12) # равноprint(x != 12) # не равноprint(x < 20) # меньшеprint(x > 20) # большеprint(x <= 12) # меньше или равноprint(x >= 15) # больше или равноЗнаки из двух символов пишутся слитно: <=, а не < =.
Сравнивать имеет смысл значения одного типа. Строка никогда не равна числу: "40" == 40 даёт False, хотя на экране оба выглядят как 40. Поэтому число из input сначала превращают через int, как в прошлом уроке.
and, or, not
and требует обоих условий, or — хотя бы одного, not меняет ответ на противоположный. Возьмём два простых условия для x = 12: a — «x чётно», b — «x больше 20»:
x = 12a = x % 2 == 0b = x > 20print(a and b)print(a or b)print(not b)a истинно, b ложно. and требует обоих — ответ False; or хватает одного — True; not переворачивает ложное b в True. У двух условий всего четыре сочетания; разложим их клетками и отметим, где выражение истинно:
and истинно в одной клетке — когда истинны оба. or ложно в одной клетке — когда ложны оба. a != b истинно на диагонали: ровно одно из двух. Точка — наш случай x = 12: a истинно, b ложно.Обрати внимание на нижнюю правую клетку or: or истинно и тогда, когда верны оба условия, — это не «одно из двух». «Ровно одно из двух» записывают как a != b: ответы двух условий различаются.
Тонкости:!= для чисел
«Ровно одно» != означает только между логическими значениями. Между числами это просто «числа различаются»: 3 != 5 — это True, и никакого «одного из двух» тут нет.
Интервал записывают цепочкой сравнений:
x = 12print(5 <= x < 20)print(5 <= x and x < 20)5 <= x < 20 — то же, что 5 <= x and x < 20: выполняются оба сравнения.
<=), пустой конец 20 — нет (<). 12 лежит внутри, поэтому ответ True.Порядок and, or, not
Сначала вычисляются сравнения, затем not, затем and и только потом or. Это похоже на арифметику, где умножение сильнее сложения: and сильнее or. Проверим на правиле високосного года: год високосный, если делится на 4 и не делится на 100 — или если делится на 400:
y = 2000print(y % 4 == 0 and y % 100 != 0 or y % 400 == 0)x = 12print(not x % 3 == 0)В первой записи Python сначала вычисляет три сравнения, затем and из первых двух, затем or с третьим. Во второй not применяется к готовому сравнению x % 3 == 0: 12 делится на 3, сравнение даёт True, а not превращает его в False.
True и False, and — False, но третье сравнение истинно, и or даёт True. Слева not стоит над всем сравнением.Если сомневаешься в порядке, ставь скобки: (y % 4 == 0 and y % 100 != 0) or y % 400 == 0 читается сразу, без знания правил.
Короткое вычисление
Python не вычисляет часть условия, которая уже не влияет на ответ. В a and b значение b не нужно, если a ложно. В a or b значение b не нужно, если a истинно. Это называют коротким вычислением.
x = 0print(x != 0 and 10 / x > 2)print(x == 0 or 10 / x > 2)10 / x при x = 0 не выполняется ни в одной строке.Деления на ноль нет ни в одной строке: правая часть не вычислялась. Порядок частей значим: проверка, которая защищает от ошибки, должна стоять раньше действия, которое без неё упадёт. Если переставить части, 10 / x > 2 and x != 0 остановится с ZeroDivisionError.
Истинность значений
Любое значение в условии считается истинным или ложным. Ноль, пустая строка и None считаются ложными; ненулевые числа и непустые строки — истинными. Позднее к ложным добавятся пустые коллекции.
None и сам False. Всё остальное истинно, в том числе строки "0", "False" и строка из одного пробела.bool(value) показывает, истинно ли значение. bool("False") равно True: строка непустая, а английское слово в ней Python не читает.
or и and возвращают одну из своих частей, а не обязательно True или False. or с ложной левой частью отдаёт правую, and с ложной левой частью отдаёт её саму: 0 and 5 — это 0. Со сравнениями этого не видно: их части и так True или False. Зато отсюда частая ошибка: «x равно 2 или 3» хочется записать как x == 2 or 3:
x = 12print(x == 2 or 3)print(x == 2 or x == 3)Python читает первую запись как (x == 2) or 3. Левая часть ложна, и or отдаёт правую — само число 3. А 3 в условии истинно, поэтому такое «условие» выполняется при любом x. Сравнение нужно повторить: x == 2 or x == 3.
Тонкости:запасное значение через or
Точное правило: or возвращает первую истинную часть, а если такой нет — последнюю; and — первую ложную или последнюю. На этом держится запись запасного значения: "" or "Без названия" даёт «Без названия», а 5 and 8 — 8.
Отрицание и импликация
Отрицание составного условия меняет and на or. Выражение not (a and b) истинно, когда хотя бы одно из условий ложно; оно равносильно (not a) or (not b). Аналогично not (a or b) равносильно (not a) and (not b). Проверим на x = 12: «неверно, что x чётно и больше 20» — то же, что «x нечётно или не больше 20»:
x = 12print(not (x % 2 == 0 and x > 20))print(x % 2 != 0 or x <= 20)Импликация «если A, то B» ложна только при истинном A и ложном B. Её можно записать (not A) or B.
В задачах ЕГЭ о логике (например, в задачах 2 и 15) встречаются импликация → и тождество ≡. В Python их записывают так: A → B — это (not A) or B, A ≡ B — это A == B: ответы двух условий совпадают.
Итог
За урок ты научился задавать программе вопросы и собирать из простых ответов сложные. В следующем уроке программа начнёт по этим ответам выбирать, что делать. Вот что понадобится дальше.
- Сравнения
== != < > <= >=даютTrueилиFalse— значения типаbool.=присваивает,==сравнивает. and, or, notОба; хотя бы одно, в том числе оба; наоборот. «Ровно одно» —a != b.- ПорядокСравнения,
not,and,or. Сомневаешься — ставь скобки. - Интервал
5 <= x < 20— то же, что5 <= x and x < 20. - Короткое вычислениеПравая часть не вычисляется, если ответ уже известен: проверка, которая защищает от ошибки, — первой.
- ИстинностьЛожны 0, пустая строка,
NoneиFalse. Пишиx == 2 or x == 3, а неx == 2 or 3. - Отрицание
not (a and b)—not a or not b;not (a or b)—not a and not b. - → и ≡A → B —
(not A) or B; A ≡ B —A == B.
Проверьте себя
Ответь сначала сам, потом открой ответ.
Что напечатает print(7 >= 7, 7 > 7)?
ОтветСкрыть ответ
True False: >= включает равенство, > — нет.
Программа из двух строк x = input() и print(x == 5). Что она напечатает, если ввести 5? Почему?
ОтветСкрыть ответ
False: input вернул строку "5", а строка не равна числу. Нужно int(input()) == 5.
Чему равно True or False and False?
ОтветСкрыть ответ
True: and выполняется раньше — False and False даёт False, затем True or False — True.
Пусть x = 0. Что случится при print(10 / x > 2 and x != 0)?
ОтветСкрыть ответ
ZeroDivisionError: левая часть вычисляется первой, а в ней деление на ноль. Проверку x != 0 нужно поставить слева.
Что напечатает print(x == 1 or 2) при x = 5? Как записать условие «x равно 1 или 2» правильно?
ОтветСкрыть ответ
2: левая часть ложна, и or отдаёт правую — число 2. Верно: x == 1 or x == 2.
Практика
Для проверки ответов нужен JavaScript. Условия, подсказки и решения доступны ниже.
Условие «делится на 3 или на 5, но не на оба сразу»
Запиши условие «n делится на 3 или на 5, но не на оба сразу». Проверь его, подставляя по очереди n = 9, 10, 7 и 15: для каждого числа программа печатает True или False.
Запишите четыре значения через пробел в порядке чисел: 9, 10, 7, 15.
Подсказка
«Ровно одно из двух условий» записывают через != между ними. Каждое условие — проверка остатка от деления.
Разбор
Например:
n = 9print((n % 3 == 0) != (n % 5 == 0))9 делится только на 3, 10 — только на 5: оба раза True. 7 не делится ни на одно, 15 — на оба: оба раза False.
Ответ: True True False False
Что напечатает программа?
print(7 > 3 and 2 > 5)print(7 > 3 or 2 > 5)print(not 7 > 3)Запишите напечатанные строки через пробел в порядке вывода.
Подсказка
Сначала вычисли каждое сравнение: 7 > 3 — True, 2 > 5 — False.
Разбор
and требует обоих — False; or хватает одного — True; not переворачивает True в False.
Ответ: False True False
Что напечатает программа?
print(0 and 10 / 0)Запишите напечатанное значение.
Подсказка
Левая часть and ложна, поэтому правая не вычисляется, а and отдаёт саму левую часть.
Разбор
0 в условии ложно. and с ложной левой частью не вычисляет правую — деления на ноль нет — и отдаёт левую часть: 0.
Ответ: 0
Что напечатает программа?
print(bool(""))print(bool("0"))print(bool(0))print(bool(" "))Запишите напечатанные строки через пробел в порядке вывода.
Подсказка
Ложны ноль и пустая строка. "0" и " " — непустые строки.
Разбор
Пустая строка ложна, "0" — непустая строка, истинна. Число 0 ложно, строка из пробела непустая — истинна.
Ответ: False True False True
Импликация A → B для трёх чисел
Пусть A — «n больше 10», B — «n чётное». Чему равна импликация A → B, то есть (not A) or B, при n = 7, 12 и 15?
Запишите три значения через пробел в порядке n: 7, 12, 15.
Подсказка
Импликация ложна только при истинном A и ложном B.
Разбор
n = 7: A ложно — импликация истинна. n = 12: A и B истинны — истинна. n = 15: A истинно, B ложно — ложна.
Ответ: True True False
Условие високосного года
Год високосный, если делится на 4 и не делится на 100 или если делится на 400. Запиши условие для y и проверь его, подставляя по очереди 1900, 2000, 2024 и 2023.
Запишите четыре значения через пробел в порядке лет: 1900, 2000, 2024, 2023.
Подсказка
and выполняется раньше or: «делится на 4 и не делится на 100» — одна пара, «делится на 400» — вторая.
Разбор
Условие: y % 4 == 0 and y % 100 != 0 or y % 400 == 0. 1900 делится на 100, но не на 400 — False. 2000 делится на 400 — True. 2024 делится на 4 и не на 100 — True. 2023 не делится на 4 — False.
Ответ: False True True False