Справочник по Python · модуль 2 · условия
Глава 2.2
Составление условий
без ветвления
В этой главе разобрано, как записать на Python словесные условия задачи: «все три», «хотя бы одно», «ровно одно», «ни одного». Оператор if здесь не используется: программа вычисляет выражение и выводит результат.
- Категория
- Синтаксис и базовые концепции
- Уровень
- Начальный
- Связанные темы
- Логический тип, ветвление, операции деления
- Зачем это знать
- Переводить словесное условие задачи в выражение на Python
§1Три формулировки условий
Условия в задачах формулируют словами. Чаще всего встречается одна из трёх формулировок.
| Формулировка | Смысл | Чем записывается |
|---|---|---|
| Каждое — «все три числа кратны трём» | истинны все условия без исключения | and |
| Хотя бы одно — «среди чисел есть отрицательное» | истинно одно или больше | or |
| Только одно — «одно число чётное, другое нет» | истинно ровно одно, остальные ложны | and и or вместе |
Первые две записываются одним оператором, третья — сочетанием двух. Ниже каждая разобрана на задаче.
§2Простая проверка: делимость
В примерах этой главы часто встречается проверка делимости. Выражение A % 3 == 0 проверяет, делится ли A на три без остатка.
В нём две части: A % 3 — остаток от деления (глава 1.8), == 0 — сравнение этого остатка с нулём. Если остаток равен нулю, число делится нацело, и выражение даёт True.
A % 2 == 0 # A чётное A % 2 != 0 # A нечётное A % 3 == 0 # A кратно трём A < 0 # A отрицательное
Каждая такая строка даёт логическое значение. Составное условие состоит из простых проверок, соединённых операторами. Читать его удобно в том же порядке: сначала определить, что проверяет каждая часть, затем — как части соединены.
§3Каждое — оператор and
Задача: проверить, что числа A, B и C кратны трём. Слово «и» между требованиями означает and.
(A % 3 == 0) and (B % 3 == 0) and (C % 3 == 0)
Операторов and в выражении может быть несколько. Выражение истинно, только если истинны все его части. Если хотя бы одно число не делится на три, результат — False.
A, B, C = 9, 6, 3 print((A % 3 == 0) and (B % 3 == 0) and (C % 3 == 0)) # True
Скобки вокруг каждой проверки не обязательны: сравнение == выполняется раньше and. В длинных условиях скобки всё же ставят: по ним видно, что выражение состоит из трёх отдельных проверок.
Python вычисляет составное условие слева направо и останавливается, когда результат уже определён. В цепочке and первое ложное условие делает ложным всё выражение, и остальные проверки не выполняются. Это правило языка, поэтому слева обычно ставят проверку, которая чаще оказывается ложной.
§4Хотя бы одно — оператор or
Задача: проверить, есть ли среди чисел A, B, C отрицательное. Достаточно одного отрицательного числа, поэтому нужен or.
A = -5 B = 10 C = 3 print((A < 0) or (B < 0) or (C < 0))
True
Результат истинный, потому что A меньше нуля. Значения B и C на него уже не влияют: оператору or достаточно одной истинной части. Выражение ложно, только когда ложны все три проверки.
§5Только одно — комбинация
Задача: проверить, что из двух чисел одно чётное, а другое нечётное — то есть ровно одно чётное.
Одним оператором это условие не записать. Перечислим случаи, в которых оно выполнено:
Aчётное иBнечётное — записывается какA % 2 == 0 and B % 2 != 0;Aнечётное иBчётное — записывается какA % 2 != 0 and B % 2 == 0;- подходит любой из двух случаев, поэтому они соединяются через
or.
(A % 2 == 0 and B % 2 != 0) or (A % 2 != 0 and B % 2 == 0)
A, B = 4, 7 print((A % 2 == 0 and B % 2 != 0) or (A % 2 != 0 and B % 2 == 0)) # True
Число 4 чётное, число 7 нечётное: истинна первая часть условия, и оператору or этого достаточно. Если оба числа чётные, обе части ложны и результат — False. Этим «ровно одно» отличается от «хотя бы одно»: когда чётны оба числа, условие не выполнено.
Скобки показывают, что or соединяет два случая целиком. Приоритет and выше, чем у or, поэтому без скобок результат тот же, но в выражении такой длины их ставят, чтобы порядок вычисления был виден.
§6Ни одного и не все
Ещё две частые формулировки получаются из разобранных с помощью not.
| Формулировка | Как записать | Через что получается |
|---|---|---|
| ни одно из чисел не отрицательно | not (A < 0 or B < 0) | отрицание «хотя бы одного» |
| то же самое напрямую | A >= 0 and B >= 0 | каждое неотрицательно |
| не все числа кратны трём | not (A % 3 == 0 and B % 3 == 0) | отрицание «каждого» |
Первые две строки таблицы описывают одно условие. Отрицание «хотя бы одного» равно «каждое наоборот», а отрицание «каждого» — «хотя бы одно наоборот». Эти правила называются законами де Моргана. При раскрытии скобок после not каждая проверка меняется на противоположную, а and и or меняются местами.
Из двух равносильных записей выбирайте ту, которая ближе к формулировке задачи. Если в условии сказано «оба числа неотрицательны» — пишите A >= 0 and B >= 0. Если «нет ни одного отрицательного» — not (A < 0 or B < 0).
§7Как собирать длинные условия
Условие из четырёх и более проверок трудно читать в одной строке. Его составляют по шагам:
- Выпишите словами каждое требование задачи отдельной строкой.
- Запишите каждое требование простой проверкой, как в §2.
- Определите связку: «и» между всеми —
and, «или» —or, «ровно одно» — комбинация. - Дайте промежуточным проверкам имена, если их больше трёх.
Сравните две записи одного условия — «человек совершеннолетний, со стажем и без задолженностей»:
print(age >= 18 and experience >= 3 and debt == 0)
is_adult = age >= 18 is_experienced = experience >= 3 has_no_debt = debt == 0 print(is_adult and is_experienced and has_no_debt)
Вторая запись длиннее на три строки, но её последняя строка читается как фраза: совершеннолетний, со стажем, без долга. То же правило действует для любых переменных: имя называет смысл значения.
§8Частые ошибки
| Что написано | Что произойдёт | Как правильно |
|---|---|---|
A % 2 == 0 or B % 2 == 0 для «ровно одного» | условие истинно и когда оба числа чётные | развернуть в два случая через and и соединить их or |
A and B < 0 | проверяется другое условие: A считается истиной при любом ненулевом значении | A < 0 and B < 0 — у каждой проверки своя левая часть |
A % 2 = 0 | SyntaxError — присваивание вместо сравнения | A % 2 == 0 |
A or B or C < 0 для «есть отрицательное» | результат почти всегда True — сравнение относится только к C | A < 0 or B < 0 or C < 0 |
not A < 0 or B < 0 | not применился только к первой проверке — приоритет выше or | not (A < 0 or B < 0) |
A % 2 == 0 and != 0 | SyntaxError — у второго сравнения нет операнда | повторить проверяемое значение полностью |
Строка A or B or C < 0 повторяет русскую фразу «A или B или C меньше нуля». Python вычисляет её иначе: сначала A как логическое значение, затем B, и только для C выполняется сравнение C < 0. Любое ненулевое число считается истиной (глава 2.1, §3). Программа при этом не останавливается с ошибкой, а выводит неверный результат. Сравнение нужно записать у каждого числа.
§9Проверьте себя
Как записать условие «все три числа положительны»?
(A > 0) and (B > 0) and (C > 0). Формулировка «все» переводится цепочкой and: достаточно одному числу оказаться неположительным, и результат станет False.
Чем условие «хотя бы одно из двух чётное» отличается от «ровно одно из двух чётное»?
Случаем, когда чётны оба. «Хотя бы одно» — это A % 2 == 0 or B % 2 == 0, и при двух чётных числах оно истинно. «Ровно одно» в этом случае должно давать False, поэтому его собирают из двух взаимоисключающих вариантов через and и or.
Что проверяет выражение A % 5 == 0 and A % 3 == 0?
Что число A делится и на пять, и на три одновременно, то есть кратно пятнадцати. Обе проверки должны быть истинными — этого требует and.
Почему not A < 0 or B < 0 и not (A < 0 or B < 0) — разные условия?
У not приоритет выше, чем у or, поэтому в первой записи отрицание относится только к A < 0: получается «A неотрицательно или B отрицательно». Во второй записи скобки задают другой порядок: сначала вычисляется всё условие, затем отрицание. Смысл — «ни одно из чисел не отрицательно».
Задача для практики: пользователь вводит три числа. Проверьте, что ровно одно из них равно нулю.
Формулировка «ровно одно» разворачивается в три случая — по одному на каждое число, — и в каждом остальные должны быть ненулевыми:
(A == 0 and B != 0 and C != 0) or(A != 0 and B == 0 and C != 0) or(A != 0 and B != 0 and C == 0)
Вторая запись короче и опирается на то, что True равно единице: (A == 0) + (B == 0) + (C == 0) == 1. Сумма истинных проверок должна равняться одному.
§10Шпаргалка
(A > 0) and (B > 0)
(A < 0) or (B < 0)
(A и не B) or (не A и B)
not (A < 0 or B < 0)
n % 2 == 0 # чётное
n % 3 == 0 # кратно 3
n < 0 # отрицательное
A < 0 or B < 0 ✓
A or B < 0 ✗
Итог главы
Формулировка «каждое» записывается цепочкой and, «хотя бы одно» — цепочкой or, «только одно» — перечислением подходящих случаев, соединённых or. Любое условие состоит из простых проверок вида A % 2 == 0. Длинное выражение делят на части и каждой дают имя. В главе 2.4 такие условия используются в операторе if.