В первой главе мы научились писать программы, в которых выполнялись все строки. Однако очень часто нам нужно, чтобы код выполнялся при определённых условиях. В таком случае используется условный оператор.
Рассмотрим его синтаксис на примере. Пусть от пользователя требуется ввести два целых числа: температуру на улице вчера и сегодня. А программа ответит — сегодня теплее, холоднее или же температура не изменилась:
yesterday_temp = int(input())
today_temp = int(input())
if today_temp > yesterday_temp:
print("Сегодня теплее, чем вчера.")
elif today_temp < yesterday_temp:
print("Сегодня холоднее, чем вчера.")
else:
print("Сегодня такая же температура, как вчера.")
Оператор if
является началом условной конструкции. Далее идёт условие, которое возвращает логическое значение True
(истина) или False
(ложь). Завершается условие символом «двоеточие». Затем — обязательный отступ в четыре пробела, он показывает, что строки объединяются в один блок. Отступ аналогичен использованию фигурных скобок или ключевых слов begin
и end
в других языках программирования.
Тело условной конструкции может содержать одно или несколько выражений (строк). По завершении тела может идти следующее условие, которое начинается с оператора elif
(сокращение от else if — «иначе если»). Оно проверяется только в случае, если предыдущее условие не было истинным.
Синтаксис в elif
аналогичен if
. Операторов elif
для одного блока условного оператора может быть несколько, а может не быть совсем. Последним идёт оператор else
, который не содержит условия, а выполняется, только если ни одно из предыдущих условий в if
и elif
не выполнилось. Оператор else
не является обязательным.
В качестве условия может выступать результат операции сравнения:
>
(больше);>=
(больше или равно);<
(меньше);<=
(меньше или равно);==
(равно);!=
(не равно).
Для записи сложных условий можно применять логические операции:
and
— логическое «И» для двух условий. ВозвращаетTrue
, если оба условия истинны, иначе возвращаетFalse
;or
— логическое «ИЛИ» для двух условий. ВозвращаетFalse
, если оба условия ложны, иначе возвращаетTrue
;not
— логическое «НЕ» для одного условия. ВозвращаетFalse
для истинного условия, и наоборот.
Ниже приведена таблица истинности для логических операций.
x | y | not x | x or y | x and y |
---|---|---|---|---|
False | False | True | False | False |
False | True | True | True | False |
True | False | False | True | False |
True | True | False | True | True |
Рассмотрим следующий пример. Пользователь должен ввести первую и последнюю буквы русского алфавита. Ввод производится в двух отдельных строках и в любом регистре.
print("Введите первую и последнюю буквы русского алфавита.")
first_letter = input()
last_letter = input()
if (first_letter == "а" or first_letter == "А") and (
last_letter == "я" or last_letter == "Я"):
print("Верно.")
else:
print("Неверно.")
В логическом операторе можно использовать двойное неравенство. Например, неравенство
if x >= 0 and x < 100:
...
лучше записать так:
if 0 <= x < 100:
...
Строки также можно сравнивать между собой с помощью операций >
, <
и т. д. В отличие от чисел, строки сравниваются посимвольно в соответствии с кодами символов в таблице кодировки (в Python рекомендуется использовать кодировку UTF-8
).
Компьютер изначально работает только с двоичными числами. Поэтому для работы с символами им назначаются коды — числа, а сами таблицы соответствия символов и кодов называются таблицами кодировки. Кодировок существует достаточно много, одной из самых популярных на данный момент является UTF-8
. Например, сравним две односимвольные строки:
letter_1 = "t"
letter_2 = "w"
print(letter_1 > letter_2)
Программа выведет False
, поскольку символ t
стоит в таблице кодировки раньше, чем w
(как и по алфавиту, то есть лексикографически). Чтобы убедиться в этом, можно использовать встроенную функцию ord()
, которая возвращает код символа из таблицы кодировки:
print(ord("t"), ord("w"))
В консоли отобразится:
116 119
Поскольку 116 меньше 119, в предыдущем примере мы и получили False
.
Чтобы получить символ по его коду, необходимо вызвать встроенную функцию chr()
с соответствующим кодом:
print(chr(116), chr(119))
В результате увидим:
t w
В таблице кодировки большие и маленькие буквы являются различными символами с разными кодами (из разных диапазонов). Поэтому для корректного сравнения строки должны быть в одном регистре.
Для проверки условия наличия подстроки в строке (и для некоторых других вещей, о которых будет рассказано позже) используется оператор in
. Например, проверим, что во введённой строке встречается корень «добр» (для слов «добрый», «доброе» и подобных):
text = input()
if "добр" in text:
print("Встретилось 'доброе' слово.")
else:
print("Добрых слов не найдено.")
В Python версии 3.10 появился оператор match
. В простейшем случае он последовательно сравнивает значение выражения с заранее заданными в операторах case
. А затем выполняет код в операторе case
, значение в котором соответствует проверяемому. Напишем программу, которая сравнивает значение текущего сигнала светофора с одним из трёх вариантов (красный, жёлтый или зелёный):
color = input()
match color:
case 'красный' | 'жёлтый':
print('Стоп.')
case 'зелёный':
print('Можно ехать.')
case _:
print('Некорректное значение.')
Обратите внимание, что для проверки выполнения условия «ИЛИ» в операторе case
не используется логическая операция or
. Её нельзя использовать, поскольку она применяется для переменных логического типа, а в примере перечисляются значения-строки. Вместо неё мы используем специальный оператор |
.
Последний оператор case
выполняется всегда и сработает в случае, если ни одно из предыдущих условий не сработало. Оператор match
похож на оператор switch
других языков программирования — C++, JavaScript и т. д.
Рассмотрим некоторые полезные встроенные функции.
- Для определения длины строки (а также других коллекций, о которых будет рассказано позже) используется функция
len()
. - Для определения максимального и минимального из нескольких значений (не только числовых) используются функции
max()
иmin()
соответственно. - Функция
abs()
используется для определения модуля числа.
Рассмотрим применение встроенных функций в следующем примере. Обратите внимание на строки, начинающиеся со знака #
. Так в Python обозначаются комментарии — линии, которые не выполняются интерпретатором, а служат для пояснения кода.
m = 12
n = 19
k = 25
# максимальное число
print(max(m, n, k))
line_1 = "m"
line_2 = "n"
line_3 = "k"
# минимальная лексикографически строка
print(min(line_1, line_2, line_3))
# количество цифр в числе 2 в степени 2022
print(len(str(2 ** 2022)))
В следующей теме вы узнаете о циклах — конструкциях, которые позволяют выполнять один и тот же код несколько раз. Для этой главы мы также подготовили задачи. Не пропускайте их, если хотите закрепить материал.
Ещё по теме
- Оператор
match
также используется для так называемой проверки шаблона (pattern matching), почитать о которой можно в этом материале. - Все доступные в Python встроенные функции можно посмотреть на этой странице.
В этой статье мы рассмотрим, пожалуй, главную часть любой программы, поскольку именно условные конструкции формируют ее структуру и делают так, чтобы запускались нужные части кода. Эти конструкции называют «сердцем» программы в любом языке программирования, и тот же искусственный интеллект по большей части построен на ветвлениях условий. Поэтому рассмотрим их подробнее в следующем порядке:
- условный оператор
if
, - конструкция
if-else
, - конструкция
if-elif-else
, - примеры программ.
Проще всего это понять на примере. Введите в интерпретаторе Python следующее и нажмите Enter для вывода:
>>> if 5 > 4:
print('Верно, 5 больше, чем 4.')Верно, 5 больше, чем 4.
Перед нами простейший пример работы программы по условию. Если переводить с Python (а это почти чистый английский — настолько порой понятен его код), мы написали буквально следующее: «Если 5 больше 4, напечатать: Верно, 5 больше, чем 4».
Таким образом, if
служит для выполнения блока кода по условию: если условие истинно (то есть Python рассматривает его как True), код блока будет исполнен, а если ложно (False), то нет. Давайте приведем и пример False, введите и нажмите Enter:
if 5 < 4:
print('Верно, 4 больше 5')
Интерпретатор молчит — и правильно делает, потому что условие ложно, а значит запись Верно, 4 больше 5 (сама по себе тоже ошибочная) никогда не будет выведена.
Но в большинстве случаев одного условия нам будет не хватать и придется использовать более сложные конструкции: if-else
и if-elif-else
.
Условная конструкция if-else
if-else
используется, когда нужно дать программе выбор: в первом случае сделать так, а во втором — иначе. Вот пример:
money = int(input('Какую сумму вы бы хотели потратить на покупки у нас? Введите цифру: '))
if money >= 100:
print('Добро пожаловать! Отправили каталог на вашу электронную почту.')
else:
print('К сожалению, у нас нет товаров дешевле 100 рублей. Заходите еще.')
input('Нажмите Enter для выхода.')
Первая строка нужна для ввода, за который отвечает инструкция input
. Если в двух словах, то функция input
состоит в приеме пользовательского ввода и, при необходимости, в передаче введенного значения в переменную (в данном случае в качестве переменной выступает money).
А далее в дело вступает условная конструкция: если введенная сумма равна или больше ста рублей, программа дает положительный ответ. Если же введенная сумма 99 рублей или меньше, выдается другой ответ.
В последней строчке мы также добавили оператор input
, который в данном случае не передает никакого значения в переменную, а нужен для перевода на следующую строку кода. А поскольку этой строки у нас нет, по нажатию Enter выполняется выход из программы: это еще одна особенность input
.
Условная конструкция if-elif-else
Давайте усложним предыдущий пример и заставим программу выбирать из трех вариантов. Сделать это можно, добавив дополнительное условие, которое будет задано оператором elif
:
money = int(input('Какую сумму вы бы хотели потратить на покупки у нас? Введите цифру: '))
if money >= 10000:
print('Рады приветствовать оптового покупателя! Для вас у нас есть специальные скидки.')
elif money >= 100:
print('Добро пожаловать! Отправили каталог на вашу электронную почту.')
else:
print('К сожалению, у нас нет товаров дешевле 100 рублей. Заходите еще.')
input('Нажмите Enter для выхода.')
Теперь, если пользователь введет сумму равную или больше указанного значения (10000), программа выдаст текст из первого блока с if
. А если сумма будет меньше этого значения, но равна или больше 100, будет выполнено условие оператора elif
, и пользователь увидит второй текст.
Чтобы вам было удобнее читать код с условиями, операторы удобно переводить так: if
— «если», elif
— «а если», else
— «в ином случае».
Добавим, что elif
может быть сколь угодно много, главное правило: в первом условии обязательно должен быть указан оператор if
. Вот пример кода с несколькими elif
. Представим, что мы хотим сгенерировать стартовую звездную систему для нашей цивилизации в космической стратегии:
import random
star = random.randint(1, 5)
planets = random.randint(1, 10)if star == 1:
print('Ваша цивилизация живет в системе голубого гиганта, вокруг которого вращаются', planets, 'планет')
elif star == 2:
print('Ваша цивилизация живет в системе белого карлика, вокруг которого вращаются', planets, 'планет')
elif star == 3:
print('Ваша цивилизация живет в системе солнцеподобного желтого карлика, вокруг которого вращаются', planets, 'планет')
elif star == 4:
print('Ваша цивилизация живет в системе оранжевого гиганта, вокруг которого вращаются', planets, 'планет')
else:
print('Ваша цивилизация живет в системе красного сверхгиганта, вокруг которого вращаются', planets, 'планет')
input('Нажмите Enter для выхода')
Вот какую систему подарил рандом нам:
Ваша цивилизация живет в системе солнцеподобного желтого карлика, вокруг которого вращаются 6 планет
Нажмите Enter для выхода
Почти солнечная, только планет поменьше. Обратите внимание, что мы создали две переменные (star и planets), генерацию значений для которых доверили модулю random
, который сначала нужно вызвать:
import random
Далее при помощи инструкции random.randint
мы задали диапазон генерируемых значений, из которого генератор случайных чисел (далее — ГСЧ) выбирает одно: для звезд из 5 и для планет из 10:
star = random.randint(1, 5)
planets = random.randint(1, 10)
Поскольку типов звезд у нас пять, блоков кода с условиями должно быть столько же, поэтому нам и пригодились несколько операторов elif
. А вот количество планет будет произвольным для любого куска кода, потому что переменная planets включена во все.
И еще один момент: вы уже заметили, что в коде одни операции обозначаются знаком =
, а другие знаком двойного равенства: ==
. В Python один знак «равно» (=
) используется только для присвоения значений переменным, а вот двойное равенство равно арифметическому. Поэтому в примере выше код:
star = random.randint(1, 5)
означает, что переменная star принимает случайное значение, сгенерированное модулем random
, а выражение:
if star == 1:
означает, что переменная star с уже присвоенным значением сравнивается со значением 1 (и в случае истинности этого условия, начинает выполняться код этого блока).
Игровые примеры для закрепления
Лучше всего учиться играя, поэтому давайте продемонстрируем, как работает условный оператор if else
в Python, на примере простейших игр, а заодно познакомимся с другими полезными функциями.
Подбрасываем монетку
Напишем такую программу с использованием условной конструкции if-elif-else
и шаг за шагом рассмотрим, как эта программа устроена. Итак, наберите в редакторе, не забывая про отступы:
import random
coin = random.randint(1, 2)
attempts = 0
orel = 0
reshka = 0while attempts < 100:
if coin == 1:
orel += 1
attempts += 1
coin = random.randint(1, 2)
elif coin == 2:
reshka += 1
attempts += 1
coin = random.randint(1, 2)
else:
print('Монетка упала ребром. Неужели такое бывает? Хорошо, перебрасываем.')
attempts += 1
coin = random.randint(1, 2)
print('Орёл выпал', orel, 'раз(-а), а решка', reshka, 'раз(-а).')
input('Нажмите Enter для выхода')
Броски монетки мы будем имитировать при помощи уже знакомого нам ГСЧ, за который отвечает модуль random
. Его мы и вызываем в первой строчке кода:
import random
Далее вводим несколько переменных:
- coin — для бросков монетки,
- attempts — для подсчета количества бросков,
- orel — будет добавлять число выпавших «орлов»,
- reshka — будет добавлять число выпавших «решек».
При подбрасывании монетки мы будем сразу же использовать ГСЧ, поэтому пишем:
coin = random.randint(1, 2)
Это значит, что значение будет генерироваться случайным образом в пределах от 1 до 2, то есть может выпасть либо единица, либо двойка. Теперь осталось присвоить эти значения орлам и решкам соответственно, указать максимальное количество бросков и сделать так, чтобы при каждом броске их число увеличивалось на один. Для этого используем условную конструкцию if-elif-else
внутри цикла while
:
while attempts < 100:
Эта часть кода означает: до тех пор пока бросков меньше 100:
if coin == 1:
orel += 1
attempts += 1
coin = random.randint(1, 2)
если ГСЧ выдал 1:
- увеличиваем количество орлов на единицу,
- увеличиваем количество бросков на единицу,
- подбрасываем монетку снова.
elif coin == 2:
reshka += 1
attempts += 1
coin = random.randint(1, 2)
То же самое, но с решкой.
else:
print('Монетка упала ребром. Неужели такое бывает? Хорошо, перебрасываем.')
attempts += 1
coin = random.randint(1, 2)
Код, добавленный на случай невозможного (ребром монетка никогда не упадет, поскольку наш ГСЧ может выдать только 1 или 2). В данном случае эта часть кода не обязательна, но заведите себе привычку добавлять последний блок с else
— «невозможные» условия порой всё же могут выполняться, поскольку программисты не всегда могут учесть все сценарии работы программы. И поэтому блок с else
в таких случаях сделает программу более стабильной в случае выполнения неучтенного условия.
Как только монетка будет подброшена в сотый раз, будет исполнен последний блок кода:
print('Орёл выпал', orel, 'раз(-а), а решка', reshka, 'раз(-а).')
input('Нажмите Enter для выхода')
Программа выйдет из цикла while
и выдаст, сколько раз выпал орел, а сколько решка: изучаем статистику и выходим. По сути, пользователю будет виден только результат примерно в таком виде:
Орёл выпал 53 раз(-а), а решка 47 раз(-а).
Нажмите Enter для выхода
Конечно, понаблюдать за работой ГСЧ интересно, но всё же играми в полной мере что генератор звезд и планет, что броски монетки назвать сложно, поэтому напишем программу поинтереснее.
Играем с компьютером в кости
В этой игре будем по очереди бросать кубики с компьютером, а в конце объявим победителя. Это делает следующий код:
import randomscore1 = 0
score2 = 0
games = 0
die1 = 0
die2 = 0
total1 = 0
die3 = 0
die4 = 0
total2 = 0
input('Бросай кости, жми Enter!n')
while score1 < 6 and score2 < 6 and games <= 11:
die1 = random.randint(1, 6)
die2 = random.randint(1, 6)
total1 = die1 + die2
print(die1, die2)
print(total1,'n')
input('Теперь я, жми Enter!n')
die3 = random.randint(1, 6)
die4 = random.randint(1, 6)
total2 = die3 + die4
print(die3, die4)
print(total2,'n')
if total1 > total2:
score1 += 1
games += 1
elif total1 < total2:
score2 += 1
games += 1
else:
games += 1
print('Ничьяn')
print('Счёт', score1, ':', score2,'n')
input('Жми Enter!n')
if score1 > score2:
input('Ты победил! Жми Enter для выхода')
elif score1 < score2:
input('Я победил! Жми Enter для выхода')
else:
input('Победила дружба! Жми Enter для выхода')
Этот код уже может показаться немного длинным и непонятным, но зато, во-первых, мы уже написали настоящую игру (пусть пока и без графики), а во-вторых, ничего сложного здесь нет, сейчас всё объясним.
Сначала вызываем уже знакомый модуль random
, затем задаем следующие переменные, которые перед началом игры будут, разумеется, равны 0:
- score1 и score2 для подсчета побед, наших и компьютера;
- games для количества партий (их мы затем ограничим, чтобы предотвратить долгую игру в случае частых ничьих);
- die1, die2, die3, die4 для бросков отдельных костей;
- total1 и total2 для подсчета суммы очков в каждом броске двух игроков: для игрока-человека это будет сумма total1 костей die1, die2, а для компьютера — total2 и die3, die4 соответственно.
Далее идет призыв к началу игры (игрок первым увидит именно это), а затем программа входит в цикл:
while score1 < 6 and score2 < 6 and games < 11:
Как видим, условий несколько, и они соединены операторами and
. Это значит, что программа выйдет из цикла, если одно из них перестанет быть истинным (то есть либо score1 или score2 станет равным 6, либо games будет равно 11). Играем почти теннисный сет: как только один из игроков выигрывает шесть партий, игра заканчивается его победой. При этом количество партий не может быть больше 11. Таким образом, если из-за ряда ничьих в партиях ни один из игроков не одержит 6 побед, игра всё равно закончится после 11-й партии.
Теперь бросает кости игрок, а программа считает их сумму (total1 = die1 + die2) и печатает результат. После по нажатию Enter то же самое делает компьютер (у него сумма будет total2 = die3 + die4). Конечно, на самом деле вся игра выполняется целиком и полностью силами ГСЧ, но так уж устроено большинство простых игр: даже за игрока здесь всё решает рандом. А мы переходим к самой важной части программы: двум блокам if-elif-else
. Первый из них является частью цикла while
:
if total1 > total2:
score1 += 1
games += 1
elif total1 < total2:
score2 += 1
games += 1
else:
games += 1
print('Ничьяn')
print('Счёт', score1, ':', score2,'n')
input('Жми Enter!n')
Тут тоже всё просто: если наша сумма больше, мы получаем очко, если в партии выиграл компьютер, очко начисляется ему, а при ничьей — никому, но партия засчитывается как сыгранная в любом случае. Далее на экран выводится текущий счет и предлагается играть дальше. Как только выполняется условие цикла while
, то есть один из игроков одержал 6 побед или количество сыгранных партий достигло 11, программа выходит из цикла и переходит к последнему блоку:
if score1 > score2:
input('Ты победил! Жми Enter для выхода')
elif score1 < score2:
input('Я победил! Жми Enter для выхода')
else:
input('Победила дружба! Жми Enter для выхода')
Первое условие с if
выполняется, когда игрок выиграл больше партий, чем компьютер. Условие с elif
— если удачливее был компьютерный оппонент. Но что если партий было сыграно 11 и при этом игроки выиграли равное число? Для этого мы и добавили блок с else
, выполнение которого выдаст на экран примирительный текст.
Осталось добавить, что Python проверяет условия последовательно и исполняет первое, которое является истинным: то есть сначала всегда будет проверено условие с if
, затем с elif
(если их несколько, то одно за другим сверху вниз) и последним с else
. Таким образом, если в сложной программе вдруг оказались выполнены сразу несколько условий, будет исполнен только тот блок, который стоит первым: учитывайте это при написании кода.
Содержание:развернуть
- Как работает if else
-
Синтаксис
-
Отступы
-
Примеры
- Оператор elif
- Заглушка pass
- if else в одну строку
- Вложенные условия
- Конструкция switch case
Фундаментальная важность условий для любого из языков программирования заключается в их возможности описывать большую часть логики работы программы.
Говоря простыми словами, конструкция if else
в Python указывает интерпретатору, следует ли выполнять определенный участок кода или нет.
Как и все прочие составные инструкции языка, оператор выбора также поддерживает свойство вложенности. Это означает, что использование if else
позволяет создавать внутри программного модуля так называемое логическое ветвление.
Как работает if else
Синтаксис
Оператор if else
в языке Python — это типичная условная конструкция, которую можно встретить и в большинстве других языков программирования.
# самый простой пример, где есть всего одно условие
a = 1
if a == 1:
print("It is true")
> It is true
Синтаксически конструкция выглядит следующим образом:
- сначала записывается часть
if
с условным выражением, которое возвращает истину или ложь; - затем может следовать одна или несколько необязательных частей
elif
(в других языках вы могли встречатьelse if
); - Завершается же запись этого составного оператора также необязательной частью
else
.
count = 1
# условное выражение может быть сколь угодно сложным,
# и может быть сколь угодно много elif-частей
if True and count == 1 and count == 2:
print("if")
elif count == 'count':
print("First elif")
elif count == 14.2:
print("Second elif")
elif count == 1:
print("Nth elif")
else:
print("Else")
> Nth elif
Для каждой из частей существует ассоциированный с ней блок инструкций, которые выполняются в случае истинности соответствующего им условного выражения.
b = 10
if b == 10:
# любое количество инструкций
print(b)
b = b * 15
b = b - 43
b = b ** 0.5
print(b)
elif b == 20:
print("You will not see me")
else:
print("And me")
> 10
> 10.344080432788601
То есть интерпретатор начинает последовательное выполнение программы, доходит до if
и вычисляет значение сопутствующего условного выражения. Если условие истинно, то выполняется связанный с if
набор инструкций. После этого управление передается следующему участку кода, а все последующие части elif
и часть else
(если они присутствуют) опускаются.
Отступы
Отступы — важная и показательная часть языка Python. Их смысл интуитивно понятен, а определить их можно, как размер или ширину пустого пространства слева от начала программного кода.
# начало кода
# код
# код
# код
# начало первого отступа
# первый отступ
# первый отступ
# начало второго отступа
# второй отступ
# второй отступ
# конец второго отступа
# конец первого отступа
Благодаря отступам, python-интерпретатор определяет границы блоков. Все последовательно записанные инструкции, чье смещение вправо одинаково, принадлежат к одному и тому же блоку кода. Конец блока совпадает либо с концом всего файла, либо соответствует такой инструкции, которая предшествует следующей строке кода с меньшим отступом.
var_a = 5
var_b = 10
var_c = 20
if var_c**2 > var_a * var_b:
# блок №1
if var_c < 100:
# блок №2
if var_c > 10:
# блок №3
var_a = var_a * var_b * var_c
# блок №2
var_b = var_a + var_c
# блок №1
var_c = var_a - var_b
print(var_a)
print(var_b)
print(var_c)
> 1000
> 1020
> -20
Таким образом, с помощью отступов появляется возможность создавать блоки на различной глубине вложенности, следуя простому принципу: чем глубже блок, тем шире отступ.
Подробнее о табуляции и отступах в Python:
Примеры
Рассмотрим несколько практических примеров использования условного оператора.
Пример №1: создание ежедневного бэкапа (например базы данных):
from datetime import datetime
def daily_backup(last_backup_date):
"""
Передаем дату последнего бэкапа.
Если прошло больше 1 дня, создаем бэкап
"""
if not last_backup_date:
print(f"creating first backup [{datetime.now().date()}] ..")
return
delta = datetime.now() - last_backup_date
if delta.days > 0:
print(f"creating backup [{datetime.now().date()}] ..")
else:
print(f"backup on [{datetime.now().date()}] already exists")
daily_backup("")
> creating first backup [2020-08-15] ..
daily_backup(datetime(2020, 8, 14))
> creating backup [2020-08-15] ..
daily_backup(datetime(2020, 8, 15))
> backup on [2020-08-15] already exists
Пример №2: Проверка доступа пользователя к системе. В данном примере if
проверяет наличие элемента в списке:
BLACK_LIST = ['192.34.12.3', '192.34.12.5', '192.34.10.23']
USERS = ['rolli34', 'constantinpetrovv', 'kate901']
def access_available(user_name, ip):
if user_name in USERS:
if ip not in BLACK_LIST:
return True
else:
print(f"write to log: user {user_name} [ip: {ip}] in block list")
else:
print(f"write to log: user {user_name} [ip: {ip}] does not exists")
return False
if access_available("rolli34", "192.34.12.111"):
print(f"Hello!!")
> Hello!!
if access_available("rolli34", "192.34.10.23"):
print(f"Hello!!")
> write to log: user rolli34 [ip: 192.34.10.23] in block list
if access_available("devnull", "192.34.10.11"):
print(f"Hello!!")
> write to log: user devnull [ip: 192.34.10.11] does not exists
Пример №3: Валидация входных данных. В примере к нам приходят данные в формате json
. Нам необходимо выбрать все записи определенного формата:
NEED = {
"name": str,
"weight": int,
"age": int,
}
def is_valid(data):
valid = True
for need_key_name, need_type in NEED.items():
# проверяем наличие ключа
if need_key_name in data:
# если ключ есть, проверяем тип значения
data_type = type(data[need_key_name])
if data_type != need_type:
print(f"type error: '{need_key_name}' is {data_type}, need: {need_type}")
valid = False
else:
print(f"key error: '{need_key_name}' does not exists")
valid = False
return valid
if is_valid({"name": "Alex"}):
print("data is valid")
>
key error: 'weight' does not exists
key error: 'age' does not exists
if is_valid({"name": "Alex", "age": "18"}):
print("data is valid")
>
key error: 'weight' does not exists
type error: 'age' is <class 'str'>, need: <class 'int'>
if is_valid({"name": "Alex", "weight": 60, "age": 18}):
print("data is valid")
> data is valid
Оператор elif
elif
позволяет программе выбирать из нескольких вариантов. Это удобно, например, в том случае, если одну переменную необходимо многократно сравнить с разными величинами.
shinobi = 'Naruto'
if shinobi == 'Orochimaru':
print('fushi tensei')
elif shinobi == 'Naruto':
print('RASENGAN')
elif shinobi == 'Sasuke':
print('chidori')
> RASENGAN
Такая конструкция может содержать сколь угодно большую последовательность условий, которые интерпретатор будет по порядку проверять.
Но помните, что первое условие всегда задается с if
Также не стоит забывать, что как только очередное условие в операторе оказывается истинным, программа выполняет соответствующий блок инструкций, а после переходит к следующему выражению.
Из этого вытекает, что даже если несколько условий истинны, то исполнению подлежит все равно максимум один, первый по порядку, блок кода с истинным условием.
Если ни одно из условий для частей if
и elif
не выполняется, то срабатывает заключительный блок под оператором еlse
(если он существует).
Заглушка pass
Оператор-заглушка pass
заменяет собой отсутствие какой-либо операции.
Он может быть весьма полезен в случае, когда в ветвлении встречается много elif
-частей, и для определенных условий не требуется выполнять никакой обработки.
Наличие тела инструкции в Python обязательно
sum = 100000
account_first = 12000
account_second = 360000
if account_first > sum:
pass
elif account_second > sum:
pass
else:
print(sum)
if else в одну строку
Во многих языках программирования условие может быть записано в одну строку. Например, в JavaScript используется тернарный оператор:
# так выглядит условие в одну строку в JavaScript
const accessAllowed = (age > 21) ? true : false;
Читается это выражение так: если age
больше 21
, accessAllowed
равен true
, иначе — accessAllowed
равен false
.
В Python отсутствует тернарный оператор
Вместо тернарного оператора, в Питоне используют инструкцию if else
, записанную в виде выражения (в одно строку):
<expression if True> if <predicate> else <expression if False>
Пример:
number = -10
abs_number = number if number >= 0 else -number
print(abs_number)
Такая конструкция может показаться сложной, поэтому для простоты восприятия, нужно поделить ее на 3 блока:
Стоит ли использовать такой синтаксис? Если пример простой, то однозначно да:
# полная версия
count = 3
if count < 100:
my_number = count
else:
my_number = 100
# сокращенная версия
count = 3
my_number = count if count < 100 else 100
Вполне читаемо смотрятся и следующие 2 примера:
x = "Kate" if "Alex" in "My name is Alex" else "Mary"
print(x)
> Kate
y = 43 if 42 in range(100) else 21
print(y)
> 43
Но если вы используете несколько условий, сокращенная конструкция усложняется и становится менее читаемой:
x = 10
result = 100 if x > 42 else 42 if x == 42 else 0
print(result)
> 0
Вложенные условия
Ограничений для уровней вложенности в Python не предусмотрено, а регулируются они все теми же отступами:
# делать код менее читаемым можно до бесконечности
def run(action):
if action:
print(some_func())
else:
if some_func():
num = one_func()
if num:
if 0 < num < 100:
print(num)
else:
print('-')
Стоит ли использовать такие вложенности? Скорее нет, чем да. Одно из положений Python Zen гласит:
Flat is better than nested (развернутое лучше вложенного).
Большая вложенность имеет следующие недостатки:
- становится трудно легко найти, где заканчивается конкретный блок;
- код становится менее читаемым и сложным для понимания;
- возможно придется прокручивать окно редактора по горизонтали.
Но что делать, если в скрипте не получается уйти от большой вложенности if-else? 🤷♂️
Чтобы уйти от большой вложенности, попробуйте не использовать оператор else
Пример выше, можно записать следующим образом:
def run(action):
if action:
print(some_func())
return
if not some_func():
return
num = one_func()
if not num:
return
if 0 < num < 100:
print(num)
return
print('-')
Конструкция switch case
В Python отсутствует инструкция switch case
В языках, где такая инструкция есть, она позволяет заменить собой несколько условий if
и более наглядно выразить сравнение с несколькими вариантами.
# пример на C++
int main() {
int n = 5;
# сравниваем значение n поочередно со значениями case-ов
switch (n) {
case 1:
cout << n;
break;
case 2:
cout << n;
break;
# так как 5 не равняется ни 1-у, ни 2-м, то выполняется блок default
default:
cout << "There is not your number";
break;
}
return 0;
}
> There is not your number
Свято место пусто не бывает, поэтому в питоне такое множественное ветвление, в обычном случае, выглядит как последовательность проверок if-elif
:
n = 5
if n == 1:
print(n)
elif n == 2:
print(n)
else:
print("There is not your number")
> "There is not your number"
Однако есть и более экзотический вариант реализации этой конструкции, задействующий в основе своей python-словари:
switch_dict = {
1: 1,
2: 2,
3: 3,
}
print(switch_dict.get(5, "There is not your number"))
> "There is not your number"
Использование словарей позволяет, в качестве значений, хранить вызовы функций, тем самым, делая эту конструкцию весьма и весьма мощной и гибкой.
Условная инструкция if-elif-else (её ещё иногда называют оператором ветвления) — основной инструмент выбора в Python. Проще говоря, она выбирает, какое действие следует выполнить, в зависимости от значения переменных в момент проверки условия.
Сначала записывается часть if с условным выражением, далее могут следовать одна или более необязательных частей elif, и, наконец, необязательная часть else. Общая форма записи условной инструкции if выглядит следующим образом:
if test1: state1 elif test2: state2 else: state3
Простой пример (напечатает ‘true’, так как 1 — истина):
>>> if 1: ... print('true') ... else: ... print('false') ... true
Чуть более сложный пример (его результат будет зависеть от того, что ввёл пользователь):
a = int(input()) if a < -5: print('Low') elif -5 <= a <= 5: print('Mid') else: print('High')
Конструкция с несколькими elif может также служить отличной заменой конструкции switch — case в других языках программирования.
Проверка истинности в Python
- Любое число, не равное 0, или непустой объект — истина.
- Числа, равные 0, пустые объекты и значение None — ложь
- Операции сравнения применяются к структурам данных рекурсивно
- Операции сравнения возвращают True или False
- Логические операторы and и or возвращают истинный или ложный объект-операнд
Логические операторы:
X and Y
Истина, если оба значения X и Y истинны.
X or Y
Истина, если хотя бы одно из значений X или Y истинно.
not X
Истина, если X ложно.
Трехместное выражение if/else
Следующая инструкция:
if X: A = Y else: A = Z
довольно короткая, но, тем не менее, занимает целых 4 строки. Специально для таких случаев и было придумано выражение if/else:
A = Y if X else Z
В данной инструкции интерпретатор выполнит выражение Y, если X истинно, в противном случае выполнится выражение Z.
>>> A = 't' if 'spam' else 'f' >>> A 't'
Для вставки кода на Python в комментарий заключайте его в теги <pre><code class=»python3″>Ваш код</code></pre>
На чтение 9 мин Просмотров 9.8к. Опубликовано 06.08.2021
Содержание
- Введение в тему
- Зачем нужны условные инструкции
- Как работает if else
- Синтаксис
- Отступы
- Примеры
- Оператор elif
- Заглушка pass
- if else в одну строку
- Конструкция switch case
Введение в тему
В программировании мы сталкиваемся с необходимостью управлять потоком выполнения программы. Это означает, что нужно ответить на вопрос: какую часть кода и сколько раз выполнить в данный момент. По сути, именно эта часть программирования является его сердцем. В этом уроке мы будем отвечать на первый вопрос. Для этого используют так называемые условные операторы.
Зачем нужны условные инструкции
Сила и важность условных операторов в том, что большая часть логики описывается именно с их помощью. Они делают одну простую, но очень важную вещь: говорят интерпретатору Питона какую часть кода выполнять (какую не выполнять) в зависимости от какого-либо условия. Эти конструкции можно вкладывать друг в друга. Это называется логическим ветвлением. Однако, стоит проявлять особую осторожность с вложенностью: каждый новый уровень вложенности увеличивает сложность кода. Сложнее читать (понимать), выше вероятность допустить ошибку.
Как работает if else
Синтаксис
Условный оператор в Python следует широко распространённому в других языках программирования синтаксису: if else. Самый простой пример:
if True:
print("Всё правильно")
# Вывод:
Всё правильно
Давайте рассмотрим, что же здесь произошло:
1. Сперва указывается if с которого начинается оператор.
2. После if указывается условие. Если значение истинно, то выполняется код, следующий в «теле» оператора. В данном случае мы, вместо условия, указали сразу True (истина).
3. Двоеточие после условия обязательно.
4. Тело оператора – инструкции, которые будут выполнены в случае истинности условия.
У этого оператора есть и расширенные возможности. Если вам нужно выполнить другой код, но только если условие ложно, используйте else:
if 1 == 2:
print("Всё правильно")
else:
print("Да нет же!")
# Вывод:
Да нет же!
В теле оператора может быть сколько угодно строк:
i = 0
if i == 0:
print("Число равно нулю")
print("И на него нельзя делить")
else:
print("На такое число делить можно")
print("Так как оно не равно нулю")
# Вывод:
Число равно нулю
И на него нельзя делить
Другими словами, выполнение программы доходит до проверки условия в операторе, а затем перенаправляется в необходимый блок кода, который будет выполняться строка за строкой до самого конца блока. Остальные блоки оператора игнорируются.
Отступы
Одной из отличительных черт языка Python является использование отступов для выделения блоков кода. Такой подход имеет ряд преимуществ и главным из них является визуальная чистота. Отступы представляют из себя пробелы или табуляции в начале строк:
# начало кода
# код
# код
# код
# первый блок кода
# код
# код
# второй блок кода
# код
# код
# конец второго блока
# конец первого блока
# продолжение основного кода
Если отступы одинакового размера и следуют строка за строкой, интерпретатор языка идентифицирует их как единый программный блок.
# Начало основного потока
# выполнения программы
яблоки = 5
груши = 10
if яблоки < груши:
# Входим в первый блок
print('Яблок меньше чем груш')
if груши > 7:
# Входим во второй блок
print('И груш больше семи')
print('Варим компот из груш')
else:
# Входим в третий блок
print('Но груш меньше семи')
print('Варим компот из яблок и груш')
else:
# Входим в четвёртый блок
print('Груш меньше чем яблок')
print('Варим компот из яблок')
# Вывод:
Яблок меньше чем груш
И груш больше семи
Варим компот из груш
И так, варьируя ширину отступов, мы можем создавать различные структуры вложенности блоков.
Примеры
Давайте рассмотрим несколько примеров из реального, «боевого» кода:
Пример №1: класс для парсинга интернет-страниц:
# coding=utf-8
from pathlib import Path
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver.firefox.options import Options
from selenium.webdriver.support import expected_conditions as ec
from selenium.webdriver.support.wait import WebDriverWait
class ObjSel:
def __init__(self):
pass
def __enter__(self):
return self
def init(self, adress, headless=True):
options = Options()
setattr(options, 'headless', headless)
caps = DesiredCapabilities().FIREFOX
caps["pageLoadStrategy"] = 'normal' # Ждём полной загрузки страницы. Если не хотим ждать- > "eager"
self.driver = webdriver.Firefox(capabilities=caps,
firefox_options=options,
executable_path=Path('geckodriver.exe'), )
self.vars = {}
self.driver.implicitly_wait(10)
self.driver.get(adress)
def web_manager(self, name, manager_type='element'):
if name is None:
print('Wrong name')
if manager_type == 'element':
if name.get('By.XPATH'):
return self.driver.find_element(By.XPATH, name['By.XPATH'])
elif name.get('By.CSS_SELECTOR'):
return self.driver.find_element(By.CSS_SELECTOR, name['By.CSS_SELECTOR'])
elif manager_type == 'clickable':
if name.get('By.XPATH'):
return WebDriverWait(self.driver, 3).until(
ec.element_to_be_clickable((By.XPATH, name['By.XPATH'])))
elif name.get('By.CSS_SELECTOR'):
return WebDriverWait(self.driver, 3).until(
ec.element_to_be_clickable((By.CSS_SELECTOR, name['By.CSS_SELECTOR'])))
elif manager_type == 'elements':
if name.get('By.XPATH'):
return self.driver.find_elements(By.XPATH, name['By.XPATH'])
elif name.get('By.CSS_SELECTOR'):
return self.driver.find_elements(By.CSS_SELECTOR, name['By.CSS_SELECTOR'])
def __exit__(self, exc_type, exc_val, exc_tb):
if 'driver' in self.__dict__.keys():
print("Удаление экземпляра Selenium")
self.driver.quit()
Здесь Вы можете увидеть несколько примеров использования условных операторов.
Пример №2: ниже приведена функция модуля queue из стандартной библиотеки. Эта функция получает значение из очереди:
def get(self, block=True, timeout=None):
with self.not_empty:
if not block:
if not self._qsize():
raise Empty
elif timeout is None:
while not self._qsize():
self.not_empty.wait()
elif timeout < 0:
raise ValueError("'timeout' must be a non-negative number")
else:
endtime = time() + timeout
while not self._qsize():
remaining = endtime - time()
if remaining <= 0.0:
raise Empty
self.not_empty.wait(remaining)
item = self._get()
self.not_full.notify()
return item
Оператор elif
Логика бывает не только бинарной, но и множественной. К примеру, что если дальнейшее выполнение программы зависит от одного из четырёх вариантов? Во многих языках программирования (особенно, старых) принято эту задачу решать так:
i = 4
if i == 1:
print("Один")
else:
if i == 2:
print("Два")
else:
if i == 3:
print("Три")
else:
if i == 4:
print("Четыре")
# Вывод:
Четыре
Но, такой код, как мы уже говорили, создаёт сложности в дальнейшем сопровождении из-за глубоких уровней вложенности. К счастью, Пайтон предоставляет более совершенный инструмент: elif. Перепишем предыдущий код:
i = 4
if i == 1:
print("Один")
elif i == 2:
print("Два")
elif i == 3:
print("Три")
elif i == 4:
print("Четыре")
# Вывод:
Четыре
Так получается нагляднее, не так ли?
Этих условий может быть не ограниченное количество. Они перебираются по очереди, пока одно из условий не окажется верным. После этого поток управления передаётся в тело elif, а после его выполнения выходит из условного оператора.
Заглушка pass
В теле условного оператора обязательно что-то должно быть указано. Если Вы хотите пропустить какое-то условие, Вы можете использовать оператор-заглушку pass.
Такой подход чаще всего используют при разработке на стадии прототипирования.
глаза = "голубые"
характер = "мягкий"
if глаза == "карие":
print('Познакомлюсь')
elif глаза == "голубые":
if характер == "мягкий":
print('Женюсь!')
else:
pass
else:
pass
# Вывод:
Женюсь!
if else в одну строку
В Python предусмотрена возможность записывать условный оператор в одну строку:
Что делать если Да if Условие else Что делать если Нет
Пример:
стакан = 1
print("Быть") if стакан / 2 >= 0.5 else print("Не быть")
# Вывод:
Быть
Но эту конструкцию стоит использовать только для простых условий и действий. Почему? Если её использовать для более сложных вещей, читаемость кода очень сильно падает. Как Вы думаете, что выведет следующий код:
x = 15
print(x // 7) if x % 3 >= 5 else print(x) if x % 4 < 2 else print(x * -1)
# Вывод:
?
Конструкция switch case
На момент написания этого урока, всё сообщество питонистов ждёт выход релиза Python 3.10. В этой версии, кроме прочего, появится, хорошо знакомое программистам из других языков, структурное сопоставление с шаблоном или switch/case. В Питоне же эта конструкция будет выглядеть как match/case. Сопоставление подразумевает определение при операторе match искомого значения, после которого можно перечислить несколько потенциальных кейсов, каждый с оператором case. В месте обнаружения совпадения между match и case выполняется соответствующий код. Пример из документации:
match x:
case host, port:
mode = "http"
case host, port, mode:
pass