2.2. Условный оператор (if)

2.2.1. Базовый синтаксис

В программах часто бывает нужно сделать так, чтобы те или иные действия выполнялись лишь при выполнении определенного условия. Для этого в питоне (ну и в других языках программирования, конечно) есть специальная команда — условный оператор, if.

Пример такой команды:

if a == 137:
    print("Угадал")

Здесь подразумевается, что есть переменная a, и команда тогда работает так: если переменная a равна 137, то вывести на экран слово «Угадал».

Соответственно, общий вид команды следующий:

if условие:
    действия

Вы пишете if, потом условие (чуть ниже поговорим, что именно можно тут писать), потом двоеточие (обязательно), и со следующей строки, причем с дополнительным отступом (пробелами в начале строки), указываются действия.

В качестве действий можно указывать любые команды питона, которые вы знаете или еще узнаете: ввод данных через input, присваивания, вывод данных, другие if’ы и что угодно еще. (Подробные примеры будут ниже.)

Такую конструкцию вы просто пишете внутри основной программы, например:

a = int(input())
if a == 137:
    print("Угадал!")
print("Программа завершена")

Тут с клавиатуры вводится число a, проверяется, равно ли оно 137, если равно, то выводится «Угадал», и независимо от значения a выводится «Программа завершена». Обратите внимание, что print("Угадал!") написано с отступом от левого края, поэтому эта команда будет выполняться, только если a==137, а вот print("Программа завершена") написано без отступа, поэтому это продолжение основной программы, а не часть if’а. Независимо от значения a после проверки (и, если надо, выполнения) if’а программа продолжит выполняться дальше, и выведет «Программа завершена».

(Конечно, напишите этот код и поэкспериментируйте с ним. Вообще, по всем примерам, которые я привожу тут и буду приводить в других темах, пишите код и экспериментируйте.)

2.2.2. Условия

Сначала подробнее поговорим про то, что можно писать в условии.

Во-первых, можно писать «простейшие» условия. Вы можете взять любые два выражения и так или иначе их сравнить. Для сравнения есть следующие операторы:

  • == проверяет на равенство: запись if a == 137: обозначает «если переменная a равна 137». Обратите внимание, что тут два знака «равно», потому что одиночный знак «равно» имеет совсем другой смысл — это присваивание, и его нельзя (и не имеет смысла) использовать в if.
  • > — больше: if a > 137: обозначает «если переменная a больше 137».
  • < — меньше.
  • >= — больше или равно. Обратите внимание, что пишется так же, как читается: «больше или равно», соответственно, >=, а вовсе не =>.
  • <= — меньше или равно. Аналогично, пишется именно <=, а не =<.
  • != — не равно.

По обе стороны от сравнения можно писать любые выражения. Можно просто переменные или числа, а можно и любые сложные выражения, например, можно написать

if sqrt(a*b+10) >= abs(2*(3-c)) + 5:

2.2.3. Логические операторы

Во-вторых, в if можно комбинировать несколько условий. Например, если вам надо проверить, что a == 10 и b == 20. Это пишется так:

if a == 10 and b == 20:

Такое условие будет выполняться, только если выполняются оба перечисленных простых условия, т.е. только если и a == 10, и b == 20.

Есть следующие такие операторы («логические операторы»):

  • and — И. Проверка ... and ... срабатывает, только если оба условия, замененные на ..., верны.
  • or — ИЛИ. Проверка ... or ... срабатывает, если верно хотя бы одно из двух указанных условий (или оба одновременно).
  • not — НЕ. Оно применяется к одному условию (а не к двум, как выше) и инвертирует его значение: not ... срабатывает, только если условие, замененное на ..., неверно.

Например:

if a == 0 or not (b > 0 and c < 0):

сработает, если a равно нулю, или если не выполняется условие «одновременно b>0 и c<0».

Обратите внимание на скобки для указания порядка действий; если бы вы написали без скобок if a == 0 or not b > 0 and c < 0:, то было бы непонятно, к чему относится not и в каком порядке надо делать действия.

Более конкретный пример про скобки: сравните следующие два выражения:

if a == 0 and (b == 0 or c == 0):
if (a == 0 and b == 0) or c == 0:

Эти выражения имеют разный смысл; например, ситуация a==1, b==1, c==0 подходит под второе выражение, но не под первое. Поймите, почему, и заодно подумайте, какие есть еще случаи, в которых значения этих выражений отличатся.

Поэтому в любых сложных логических выражениях надо обязательно ставить скобки для указания порядка действий. Запись просто if a == 0 and b == 0 or c == 0 обозначает непонятно что. Конечно, компьютер выберет некоторый порядок действий, но лучше всегда указать его явно.

Еще замечу, что выше все примеры для простоты были с разными переменными и с простыми сравнениями. Конечно, с логическими операторами можно использовать любые другие выражения, например

if a + 24 < b * 3 or (sqrt(a + 2) > b + a and a > 3):

И наконец, логические операторы работают только с логическими выражениями — со сравнениями, либо с выражениями, которые уже составлены из сравнений и логических операторов. То есть следующая запись:

if a or b == 0:

вовсе не обозначает «если a или b равны нулю», потому что сравнение ==0 тут относится только к b, а левая часть оператора or, в которой написано просто a, не является сравнением. Запись if a: не имеет смысла (представьте себе, что a==40; что тогда обозначает запись «если 40»? Не «если 40 больше нуля», а просто «если 40»), потому и запись a or b == 0 не имеет смысла. И даже если вы поставите скобки: if (a or b) == 0, это тоже не будет работать, потому что совершенно непонятно, чему равно, например, 40 or 30.

Примечание

На самом деле сказанное в предыдущем абзаце, конечно же, не совсем верно. Запись if a: в питоне обозначает «если a не равно нулю», соответственно запись if a or b == 0 обозначает «если a не равно нулю, или b равно нулю». Но это вовсе не то, чего вы могли ожидать, и вообще, таким наявным сравнением с нулем лучше не пользоваться, за исключением особых случаев. Если вы хотите сравнить переменную с нулем, так явно и пишите: if a == 0 и т.п.

Примечание

Запись if (a or b) == 0 тоже на самом деле имеет некоторый смысл, но тоже не тот, который вы можете подумать. Но поясню эту ситуацию чуть подробнее. Питон, как и любой язык программирования — он достаточно формален и не понимает чистого человеческого языка, пусть даже иногда кажется, что понимает. В частности, любые выражения, что арифметические, что вот такие логические, питон вычисляет по порядку. Вас в школе учили вычислять значение арифметических выражений с учетом порядка действий: например, если есть выражение 10 + 20 * 30, то надо сначала умножить 20 * 30, получить 600, и потом вычислить 10 + 600. Аналогично выражение (a or b) == 0 вычисляется так: надо сначала вычислить a or b, и только полученный результат уже сравнивать с нулем. А вовсе не сравнить с нулем отдельно a и отдельно b, как вы могли бы подумать.

Примечание

И конечно тут правильнее говорить про логический тип данных — это собственно то, что получается в результате сравнений и логических операций, и то, что можно использовать в if. Это тип данных, который может хранить только два значения, которые в питоне называются True (истина, условие верно) и False (ложь, условие неверно), например, у выражения 10 > 0 результат будет True, а у выражения True and False результат будет False. И, например, если у вас написано:

(10 > 0) and (8 > 10)

то питон поступает так: он сначала вычисляет значение 10 > 0, получает True, потом вычисляет 8 > 10, получает False, потом вычисляет True and False, получает False, т.е. условие не верно.

Но для базового понимания того, как работает if, это пока не нужно.

2.2.4. Тело условного оператора

«Тело» любой составной команды (правда, вы пока знаете только про if) — это другие команды, которые выполняются внутри нее. Там можно писать вообще любые другие команды. Главное — писать с отступом, чтобы питон понял, что это часть if’а, а не продолжение основной программы.

Пример:

...
if a == 0:
    print("Ноль")
    b = int(input())
    if b == 0:
        print("И это тоже ноль!")
    print("-----")

Обратите внимание, что внутри if можно писать еще один if, и его тело будет с дополнительным отступом. Т.е. тут print("И это тоже ноль!") выполнится, только если b тоже оказалось равно нулю, а вот print("-----") выполнится независимо от b (но, конечно, надо, чтобы a было нулем).

Еще раз повторю то, что я писал в предыдущем разделе: питон, как и любой другой язык программирования ­— это конструктор. Все программирование состоит в том, что вы собираете большую программу из маленьких команд — кирпичиков. Соответственно, внутри if’а можно использовать любые другие такие кирпичики.

2.2.5. else и elif

То, что мы писали выше — это, как говорят, краткая форма if. Она указывает только что делать, если условие выполнилось. Есть полная форма if, она указывает, что делать, если условие выполнилось, а что делать, если оно не выполнилось:

if a == 0:
    print("Ноль")
else:
    print("Не ноль")

Часть «что делать, если условие не выполнилось», начинается с команды else: (с двоеточием!), причем она должна быть на том же уровне отступа, что и сам if. Под else, как и под if, можно писать любые команды, тоже с дополнительным отступом.

Пример:

if a == 0:
    if b == 0:
        print("Два нуля")
    else:
        print("Только b не ноль")
else:
    if b == 0:
        print("Только a не ноль")
    else:
        print("Обе переменные не нули")

Естественно, в else нельзя писать никаких еще условий — питон будет выполнять там код всегда, если условие соответствующего if не выполнилось. Иногда бывает нужно, если условие if не выполнилось, то проверить какое-нибудь еще условие. Это, конечно, можно писать так:

if a < 0:
    print("Отрицательное")
else:
    if a == 0:
        print("Ноль")
    else:
        print("Положительное")

Но это длинновато и сложно, плюс если таких вариантов много, то получится очень большой отступ. Поэтому есть еще специальная команда elif, обозначающая else if. Можно писать так:

if a < 0:
    print("Отрицательное")
elif a == 0:
    print("Ноль")
else:
    print("Положительное")

Это полный эквивалент предыдущего кода, только чуть покороче и — главное — без лишних отступов ступенькой. Еще раз: elif — это просто сокращение от else if, позволяющее чуть красивее писать код, ничего больше.

Еще пример:

if d = "Notrh":
    print("Идем на север")
elif d == "South":
    print("Идем на юг")
elif d == "West":
    print("Идем на запад")
elif d == "East":
    print("Идем на восток")
else:
    print("??!!")

То же самое можно было бы написать и через else/if, но были бы очень некрасивые отступы.