Книга: Изучаем Python: программирование игр, визуализация данных, веб-приложения. 3-е изд. дополненное и переработанное
Назад: 4. Работа со списками
Дальше: 6. Словари

5. Оператор if

17748.png

 

Программисту часто приходится проверять наборы условий и принимать решения в зависимости от этих условий. Оператор if в языке Python позволяет проверить текущее состояние программы и выбрать дальнейшие действия в зависимости от результатов проверки.

В этой главе вы научитесь писать условные проверки для любых интересующих вас условий. Мы начнем с простых операторов if, а затем перейдем к более сложным сериям операторов if для проверки комбинированных условий. Затем эта концепция будет применена к спискам; вы узнаете, как написать цикл, который выполняет с большинством элементов списка одну операцию, но для некоторых элементов с конкретными значениями применяется особая обработка.

Простой пример

Следующий короткий пример показывает, как правильно организовать обработку специальных ситуаций с помощью оператора if. Допустим, у вас есть список машин и вы хотите вывести название каждой из них. Названия большинства машин должны записываться с капитализацией (первая буква в верхнем регистре, остальные в нижнем). Однако значение 'bmw' должно записываться в верхнем регистре. Код ниже перебирает список названий машин и ищет в нем значение 'bmw'. Для всех элементов, содержащих это значение, оно выводится в верхнем регистре:

cars.py

cars = ['audi', 'bmw', 'subaru', 'toyota']

 

for car in cars:

❶     if car == 'bmw':

        print(car.upper())

    else:

        print(car.title())

Цикл в этом примере сначала проверяет, содержит ли car значение 'bmw' . Если проверка дает положительный результат, то значение выводится в верхнем регистре. Если car содержит все что угодно, кроме 'bmw', то при выводе значения применяется капитализация:

Audi

BMW

Subaru

Toyota

В этом примере объединяются несколько концепций, о которых вы узнаете в данной главе. Для начала рассмотрим основные конструкции, применяемые для проверки условий в программах.

Проверка условий

В каждом операторе if центральное место занимает выражение, результатом которого является логическая истина (True) или логическая ложь (False); это выражение называется проверкой условия (conditional test). В зависимости от результата проверки Python решает, должен ли выполняться код в операторе if. Если результат условия равен True, то Python выполняет код, следующий за оператором if. Если же получен результат False, то Python игнорирует этот код.

Проверка равенства

Во многих условиях текущее значение переменной сравнивается с конкретным значением, интересующим вас. Простейшее условие проверяет, равно ли значение переменной конкретной величине:

>>> car = 'bmw'

>>> car == 'bmw'

True

В первой строке переменной car присваивается значение 'bmw'; операция выполняется с помощью одного знака =, как вы уже неоднократно видели. Вторая строка проверяет, равно ли значение car строке 'bmw'; для проверки используется двойной знак равенства (==). Это оператор равенства (equality operator), и он возвращает True, если значения слева и справа от оператора равны; если же значения не совпадают, то оператор возвращает False. В нашем примере значения совпадают, поэтому Python возвращает True.

Если car принимает любое другое значение вместо 'bmw', то проверка возвращает False:

>>> car = 'audi'

>>> car == 'bmw'

False

Одиночный знак равенства выполняет операцию; первую строку кода можно прочитать как «Присвоить car значение 'audi'». С другой стороны, двойной знак равенства, как во второй строке кода, задает вопрос: «Значение car равно 'bmw'?» Такое применение знаков равенства встречается во многих языках программирования.

Проверка равенства без учета регистра

В языке Python проверка равенства выполняется с учетом регистра. Например, два значения с разным регистром символов равными не считаются:

>>> car = 'Audi'

>>> car == 'audi'

False

Если регистр символов важен, то такое поведение приносит пользу. Но если проверка должна выполняться на уровне символов без учета регистра, то преобразуйте значение переменной в нижний регистр перед выполнением сравнения:

>>> car = 'Audi'

>>> car.lower() == 'audi'

True

Условие возвращает True независимо от регистра символов 'Audi', поскольку теперь проверка выполняется без учета регистра. Метод lower() не изменяет значения, которое изначально хранилось в car, так что сравнение не отражается на исходной переменной:

>>> car = 'Audi'

>>> car.lower() == 'audi'

True

>>> car

'Audi'

Сначала строка 'Audi' сохраняется в переменной car. Затем значение car приводится к нижнему регистру и сравнивается со значением строки 'audi', также записанным в нижнем регистре. Две строки совпадают, поэтому Python возвращает True. Вывод показывает, что значение, хранящееся в car, не изменилось при вызове метода lower().

Сайты устанавливают определенные правила для данных, вводимых пользователями подобным образом. Например, он может использовать проверку условия, чтобы убедиться в том, что имя каждого пользователя уникально (а не совпадает с именем другого пользователя, отличаясь от него только регистром символов). Когда кто-то указывает новое имя пользователя, оно преобразуется в нижний регистр и сравнивается с версиями всех существующих имен в нижнем регистре. Во время такой проверки имя 'John' будет отклонено, если в системе уже используется любая разновидность 'john'.

Проверка неравенства

Если вы хотите проверить, что два значения различны, используйте комбинацию из восклицательного знака и знака равенства (!=) — оператор неравенства (inequality operator). Чтобы познакомиться с ним, мы воспользуемся другим оператором if. В переменной хранится заказанная начинка (topping) к пицце; если клиент не заказал анчоусы (anchovies), то программа выводит сообщение:

toppings.py

requested_topping = 'mushrooms'

 

if requested_topping != 'anchovies':

    print("Hold the anchovies!")

Код сравнивает значение requested_topping со значением 'anchovies'. Если эти два значения не равны, то Python возвращает True и выполняет код, следующий за оператором if. Если равны, то возвращает False и не выполняет этот код.

Значение requested_topping отличается от 'anchovies', поэтому функция print() будет выполнена:

Hold the anchovies!

В большинстве условных выражений, которые вы будете использовать в программах, будет проверяться равенство, но иногда проверка неравенства оказывается более эффективной.

Сравнения чисел

Проверка числовых значений достаточно проста. Например, следующий код проверяет, что переменная age равна 18:

>>> age = 18

>>> age == 18

True

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

magic_number.py

answer = 17

if answer != 42:

    print("That is not the correct answer. Please try again!")

Условие выполняется, поскольку значение answer (17) не равно 42. Так как условие истинно, блок с отступом выполняется:

That is not the correct answer. Please try again!

В условные операторы также можно добавлять всевозможные математические сравнения: меньше, меньше или равно, больше, больше или равно:

>>> age = 19

>>> age < 21

True

>>> age <= 21

True

>>> age > 21

False

>>> age >= 21

False

Все эти математические сравнения могут использоваться в операторах if, что повышает точность формулировки интересующих вас условий.

Проверка нескольких условий

Иногда необходимо проверить несколько условий одновременно. Например, в одних случаях выполнение действия требует, чтобы истинными были сразу два условия; в других достаточно того, чтобы истинным было хотя бы одно из них. Ключевые слова and и or помогут вам в подобных ситуациях.

Ключевое слово and для проверки нескольких условий

Чтобы проверить, истинны ли два условия, объедините их ключевым словом and; если истинны, то и все выражение тоже истинно. Если хотя бы одно (или оба) условие ложно, то и результат всего выражения равен False.

Например, чтобы убедиться в том, что каждому из двух человек больше 21 года, используйте следующую проверку:

>>> age_0 = 22

>>> age_1 = 18

❶ >>> age_0 >= 21 and age_1 >= 21

False

❷ >>> age_1 = 22

>>> age_0 >= 21 and age_1 >= 21

True

В коде определяются две переменные, age_0 и age_1. Затем программа проверяет, что оба значения равны 21 или более . Левое условие выполняется, а правое нет, поэтому все условное выражение дает результат False. Затем переменной age_1 присваивается значение 22 . Теперь значение age_1 больше 21; обе проверки проходят, а все условное выражение дает результат True.

Чтобы улучшить читабельность кода, отдельные условия можно заключить в круг­лые скобки, но это необязательно. При наличии круглых скобок проверка может выглядеть так:

(age_0 >= 21) and (age_1 >= 21)

Ключевое слово or для проверки нескольких условий

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

Вернемся к примеру с возрастом, однако на этот раз проверим, что хотя бы одна из двух переменных больше 21:

>>> age_0 = 22

>>> age_1 = 18

❶ >>> age_0 >= 21 or age_1 >= 21

True

❷ >>> age_0 = 18

>>> age_0 >= 21 or age_1 >= 21

False

Как и в предыдущем случае, сначала определяются две переменные. Условие для age_0 истинно , поэтому все выражение дает результат True. Затем значение age_0 уменьшается до 18. При проверке оба условия оказываются ложными, и общий результат всего выражения тоже False .

Проверка вхождения значений в список

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

Чтобы узнать, присутствует ли заданное значение в списке, воспользуйтесь ключевым словом in. Допустим, вы пишете программу для пиццерии. Вы создали список начинок, заказанных клиентом, и хотите проверить, входят ли некоторые начинки в этот список.

>>> requested_toppings = ['mushrooms', 'onions', 'pineapple']

>>> 'mushrooms' in requested_toppings

True

>>> 'pepperoni' in requested_toppings

False

Благодаря ключевому слову in Python получает указание проверить, входят ли значения 'mushrooms' и 'pepperoni' в список requested_toppings. Этот прием весьма полезен, поскольку вы можете создать список значений, важных для вашей программы, а затем легко проверить, есть ли проверяемое значение в списке.

Проверка отсутствия значения в списке

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

banned_users.py

banned_users = ['andrew', 'carolina', 'david']

user = 'marie'

 

if user not in banned_users:

    print(f"{user.title()}, you can post a response if you wish.")

Оператор if читается достаточно четко: если пользователь не входит в черный список banned_users, то Python возвращает True и выполняет строку с отступом.

Пользователь 'marie' не входит в этот список, поэтому программа выводит соответствующее сообщение:

Marie, you can post a response if you wish.

Логические выражения

В процессе изучения программирования вы рано или поздно услышите термин «логическое выражение» (Boolean expression). По сути, это всего лишь другое название для проверки условия. Логическое значение (Boolean value) равно True или False, как и результат условного выражения после его вычисления.

Логические значения часто используются для проверки некоторых условий — например, запущена ли компьютерная игра или разрешено ли пользователю редактирование некой информации на сайте:

game_active = True

can_edit = False

Логические значения предоставляют эффективные средства для контроля состоя­ния программы или определенного условия, играющего важную роль в вашей программе.

Упражнения

5.1. Проверка условий. Напишите последовательность условий. Выведите описание каждой проверки и ваш прогноз относительно ее результата. Код должен выглядеть примерно так:

car = 'subaru'

print("Is car == 'subaru'? I predict True.")

print(car == 'subaru')

 

print("\nIs car == 'audi'? I predict False.")

print(car == 'audi')

• Внимательно просмотрите результаты. Убедитесь в том, что понимаете, почему результат каждой строки равен True или False.

• Создайте как минимум 10 условий. Не менее пяти одних должны давать результат True, а не менее пяти других — результат False.

5.2. Больше проверок условий. Количество условий не ограничивается десятью. Попробуйте написать другие условия и добавить их в файл conditional_tests.py. Программа должна выдавать по крайней мере один истинный и один ложный результат для следующих видов проверок:

 проверка равенства и неравенства строк;

• проверки с использованием метода lower();

• числовые проверки равенства и неравенства, условий «больше», «меньше», «больше или равно», «меньше или равно»;

• проверки с помощью ключевых слов and и or;

• проверка вхождения элемента в список;

• проверка отсутствия элемента в списке.

Использование операторов if

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

Простые операторы if

Простейшая форма оператора if состоит из одного условия и одного действия:

if проверка_условия:

    действие

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

Допустим, имеется переменная, представляющая возраст человека. Следующий код проверяет, достаточен ли этот возраст для голосования:

voting.py

age = 19

if age >= 18:

    print("You are old enough to vote!")

Python проверяет, больше или равно 18 значение переменной age. В таком случае выполняется вызов функции print() в строке с отступом:

You are old enough to vote!

Отступы в операторах if играют ту же роль, что и в циклах for. Если условие истинно, то все строки с отступом после оператора if выполняются, а если ложно — весь блок с отступом игнорируется.

Блок оператора if может содержать сколько угодно строк. Добавим еще одну строку для вывода дополнительного сообщения в том случае, если возраст достаточен для голосования:

age = 19

if age >= 18:

    print("You are old enough to vote!")

    print("Have you registered to vote yet?")

Условие выполняется, а оба вызова функции print() имеют отступ, поэтому выводятся оба сообщения:

You are old enough to vote!

Have you registered to vote yet?

Если значение age меньше 18, то программа ничего не выводит.

Операторы if-else

Часто в программе необходимо выполнить разные действия в зависимости от того, истинно условие или ложно. Синтаксис if-else делает это возможным. Блок if-else в целом похож на оператор if, но оператор else определяет действие или набор действий, выполняемых при неудачной проверке.

В следующем примере выводится то же сообщение, которое выводилось ранее, если возраст достаточен для голосования, однако на этот раз при любом другом возрасте выдается другое сообщение:

age = 17

if age >= 18:

    print("You are old enough to vote!")

    print("Have you registered to vote yet?")

❷ else:

    print("Sorry, you are too young to vote.")

    print("Please register to vote as soon as you turn 18!")

Если условие истинно, то выполняется первый блок с вызовами функции print(). Если ложно, то выполняется блок else . Так как значение age на этот раз меньше 18, условие оказывается ложным и выполняется код в блоке else:

Sorry, you are too young to vote.

Please register to vote as soon as you turn 18!

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

Цепочки if-elif-else

Нередко в программе требуется проверять несколько возможных ситуаций; для таких ситуаций в Python предусмотрен синтаксис if-elif-else. Python выполняет только один блок в цепочке if-elif-else. Все условия проверяются по порядку до тех пор, пока одно из них не даст истинного результата. Далее выполняется код, следующий за этим условием, а все остальные проверки Python пропускает.

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

• для посетителей младше 4 лет вход бесплатный;

• для посетителей от 4 до 18 лет билет стоит 25 долларов;

• для посетителей от 18 лет и старше билет стоит 40 долларов.

Как использовать оператор if для определения платы за вход? Следующий код выясняет, к какой возрастной категории относится посетитель, и выводит сообщение со стоимостью билета:

amusement_park.py

age = 12

❶ if age < 4:

    print("Your admission cost is $0.")

❷ elif age < 18:

    print("Your admission cost is $25.")

❸ else:

    print("Your admission cost is $40.")

Условие if проверяет, что возраст посетителя меньше 4 лет. Если условие истинно, то программа выводит соответствующее сообщение и Python пропускает остальные проверки. Строка elif в действительности является еще одной проверкой if, которая выполняется только в том случае, если предыдущая проверка завершилась неудачей. В этом месте цепочки известно, что возраст посетителя не меньше 4 лет, поскольку первое условие было ложным. Если посетителю меньше 18 лет, то программа выводит соответствующее сообщение и Python пропускает блок else. Если ложны оба условия — if и elif, то Python выполняет код в блоке else .

В данном примере условие if дает ложный результат, поэтому его блок не выполняется. Однако условие elif оказывается истинным (12 меньше 18), поэтому код будет выполнен. Вывод состоит из одного сообщения с ценой билета:

Your admission cost is $25.

При любом значении возраста больше 17 первые два условия ложны. В таких ситуациях блок else будет выполнен и цена билета составит 40 долларов.

Вместо того чтобы выводить сообщение с ценой билета в блоках if-elif-else, лучше использовать другое, более компактное решение: присвоить цену в цепочке if-elif-else, а затем добавить один вызов функции print() после выполнения цепочки:

age = 12

 

if age < 4:

    price = 0

elif age < 18:

    price = 25

else:

    price = 40

 

print(f"Your admission cost is ${price}.")

Строки с отступами присваивают значение price в зависимости от значения age, как и в предыдущем примере. После присваивания цены в цепочке if-elif-else отдельный вызов функции print() без отступа использует это значение для вывода сообщения с ценой билета.

Этот пример выводит тот же результат, что и предыдущий, но цепочка if-elif-else имеет более узкую специализацию. Вместо того чтобы определять цену и выводить сообщения, она просто определяет цену билета. Помимо повышения эффективности, этот код имеет еще одно преимущество: его легче изменить. Чтобы изменить текст выходного сообщения, достаточно отредактировать всего один вызов функции print() вместо трех разных вызовов.

Серии блоков elif

Код может содержать сколько угодно блоков elif. Например, если парк аттракционов введет особую скидку для пожилых посетителей, то вы можете добавить в свой код еще одну проверку для определения того, распространяется ли скидка на текущего посетителя. Допустим, посетители в возрасте 65 и выше платят половину обычной цены билета, или 20 долларов:

age = 12

 

if age < 4:

    price = 0

elif age < 18:

    price = 25

elif age < 65:

    price = 40

else:

    price = 20

 

print(f"Your admission cost is ${price}.")

Бо́льшая часть кода осталась неизменной. Второй блок elif теперь проверяет, что посетителю меньше 65 лет, прежде чем назначить ему полную цену билета в 40 долларов. Обратите внимание: значение, присвоенное в блоке else, должно быть заменено на 20 долларов, поскольку в этот блок попадают только посетители в возрасте 65 лет и старше.

Исключение блока else

Python не требует, чтобы цепочка if-elif непременно завершалась блоком else. В одних случаях этот блок удобен; в других лучше использовать дополнительный оператор elif для обработки конкретного условия:

age = 12

 

if age < 4:

    price = 0

elif age < 18:

    price = 25

elif age < 65:

    price = 40

elif age >= 65:

    price = 20

 

print(f"Your admission cost is ${price}.")

Последний блок elif назначает цену 20 долларов, если возраст посетителя — 65 лет и старше; смысл такого кода более понятен, чем у обобщенного блока else. Благодаря такому изменению выполнение каждого блока возможно только при истинности конкретного условия.

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

Проверка нескольких условий

Цепочки if-elif-else эффективны, но подходят только в том случае, если истинным должно быть лишь одно условие. Как только Python находит выполняющееся условие, все остальные проверки пропускаются. Такое поведение достаточно эффективно, поскольку позволяет проверить одно конкретное условие.

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

Вернемся к примеру с пиццей. Если кто-то закажет пиццу с двумя начинками, то программа должна обработать обе:

toppings.py

requested_toppings = ['mushrooms', 'extra cheese']

 

if 'mushrooms' in requested_toppings:

    print("Adding mushrooms.")

❶ if 'pepperoni' in requested_toppings:

    print("Adding pepperoni.")

if 'extra cheese' in requested_toppings:

    print("Adding extra cheese.")

 

print("\nFinished making your pizza!")

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

В этом коде проверяются все возможные варианты начинок, поэтому в заказ будут добавлены две начинки из трех:

Adding mushrooms.

Adding extra cheese.

 

Finished making your pizza!

Если бы в программе использовался блок if-elif-else, то код функционировал бы неправильно, поскольку прерывал бы работу после обнаружения первого истинного условия. Вот как это выглядело бы:

requested_toppings = ['mushrooms', 'extra cheese']

 

if 'mushrooms' in requested_toppings:

    print("Adding mushrooms.")

elif 'pepperoni' in requested_toppings:

    print("Adding pepperoni.")

elif 'extra cheese' in requested_toppings:

    print("Adding extra cheese.")

 

print("\nFinished making your pizza!")

Первое же проверяемое условие (для 'mushrooms') оказывается истинным, поэтому в пиццу добавляются грибы. Однако значения 'extra cheese' и 'pepperoni' не проверяются никогда, поскольку в цепочках if-elif-else после обнаружения первого истинного условия все остальные пропускаются. В результате в пиццу будет добавлена только первая из заказанных начинок:

Adding mushrooms.

 

Finished making your pizza!

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

Упражнения

5.3. Цвета пришельцев 1. Представьте, что в вашей компьютерной игре только что был подбит корабль пришельцев. Создайте переменную alien_color и присвойте ей значение 'green', 'yellow' или 'red'.

• Напишите оператор if для проверки того, что переменная содержит значение 'green'. Если условие истинно, то выведите сообщение о том, что игрок только что заработал 5 очков.

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

5.4. Цвета пришельцев 2. Выберите цвет, как это было сделано в упражнении 5.3, и напишите цепочку if-else.

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

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

 Напишите одну версию программы, в которой выполняется блок if, и другую, в которой выполняется блок else.

5.5. Цвета пришельцев 3. Преобразуйте цепочку if-else из упражнения 5.4 в цепочку if-elif-else.

 Если переменная содержит значение 'green', выведите сообщение о том, что игрок только что заработал 5 очков.

 Если переменная содержит значение 'yellow', выведите сообщение о том, что игрок только что заработал 10 очков.

 Если переменная содержит значение 'red', выведите сообщение о том, что игрок только что заработал 15 очков.

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

5.6. Периоды жизни. Напишите цепочку if-elif-else для определения периода жизни человека. Присвойте значение переменной age, а затем выведите сообщение, в котором указывается тот или иной период:

 если значение меньше 2 — «младенец»;

 если значение больше или равно 2, но меньше 4 — «малыш»;

 если значение больше или равно 4, но меньше 13 — «ребенок»;

 если значение больше или равно 13, но меньше 20 — «подросток»;

 если значение больше или равно 20, но меньше 65 — «взрослый»;

 если значение больше или равно 65 — «пожилой человек».

5.7. Любимый фрукт. Составьте список своих любимых фруктов. Напишите серию независимых операторов if для проверки того, присутствуют ли некоторые фрукты в списке.

 Создайте список трех своих любимых фруктов и назовите его favorite_fruits.

 Напишите пять операторов if. Каждый должен проверять, входит ли определенный тип фрукта в список. Если входит, то блок if должен выводить сообщение вида «Вы очень любите бананы!»

Использование операторов if со списками

Объединение операторов if со списками открывает ряд интересных возможностей. Например, вы можете отслеживать специальные значения, которые нуждаются в особой обработке по сравнению с другими значениями в списке, или эффективно управлять изменяющимися условиями — например, наличием некоторых блюд в ресторане. Кроме того, объединение операторов if со списками помогает продемонстрировать, что ваш код корректно работает во всех возможных ситуациях.

Проверка специальных значений

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

Вернемся к примеру с пиццерией. Программа выводит сообщение каждый раз, когда в пиццу добавляется начинка в процессе приготовления. Код этого действия можно записать чрезвычайно эффективно: создать список начинок, заказанных клиентом, и использовать цикл для перебора всех заказанных по мере их добавления в пиццу:

toppings.py

requested_toppings = ['mushrooms', 'green peppers', 'extra cheese']

 

for requested_topping in requested_toppings:

    print(f"Adding {requested_topping}.")

 

print("\nFinished making your pizza!")

Вывод достаточно тривиален, поэтому код сводится к простому циклу for:

Adding mushrooms.

Adding green peppers.

Adding extra cheese.

 

Finished making your pizza!

А если в пиццерии вдруг кончится зеленый перец? Оператор if в цикле for может правильно обработать эту ситуацию:

requested_toppings = ['mushrooms', 'green peppers', 'extra cheese']

 

for requested_topping in requested_toppings:

    if requested_topping == 'green peppers':

        print("Sorry, we are out of green peppers right now.")

    else:

        print(f"Adding {requested_topping}.")

 

print("\nFinished making your pizza!")

На этот раз программа проверяет каждый заказанный элемент перед добавлением его в пиццу. Оператор if проверяет, заказал ли клиент зеленый перец, и если заказал — выводит сообщение о том, что этой начинки нет. Блок else гарантирует, что все другие начинки будут включены в заказ.

Из выходных данных видно, что все заказанные начинки обрабатываются правильно:

Adding mushrooms.

Sorry, we are out of green peppers right now.

Adding extra cheese.

 

Finished making your pizza!

Проверка наличия содержимого в списке

Для всех списков, с которыми мы работали до сих пор, действовало одно простое предположение: мы считали, что в каждом списке есть хотя бы один элемент. Скоро мы предоставим пользователю возможность вводить информацию, хранящуюся в списке, поэтому уже не можем предполагать, что при каждом выполнении цикла в списке есть хотя бы один элемент. В такой ситуации перед выполнением цикла for будет полезно проверить содержимое списка.

Выясним, есть ли элементы в списке заказанных начинок, перед изготовлением пиццы. Если список пуст, то программа предлагает пользователю подтвердить, что он хочет обычную пиццу. Если в списке что-то есть, то пицца готовится так же, как в предыдущих примерах:

requested_toppings = []

 

if requested_toppings:

    for requested_topping in requested_toppings:

        print(f"Adding {requested_topping}.")

    print("\nFinished making your pizza!")

else:

    print("Are you sure you want a plain pizza?")

На этот раз мы начинаем с пустого списка заказанных начинок. Вместо того чтобы сразу переходить к циклу for, программа сначала выполняет проверку. Когда имя списка используется в условии if, Python возвращает True, если список содержит хотя бы один элемент; в случае пустого списка возвращается значение False. Если requested_toppings проходит проверку условия, то выполняется тот же цикл for, который мы использовали в предыдущем примере. Если же условие ложно, то программа выводит сообщение, которое предлагает клиенту подтвердить, действительно ли он хочет получить обычную пиццу без начинок.

В данном примере список пуст, поэтому выводится сообщение:

Are you sure you want a plain pizza?

Если в списке есть хотя бы один элемент, то в выходные данные добавляется каждая заказанная начинка.

Множественные списки

Посетители могут заказать что угодно, особенно когда речь заходит о начинках пиццы. Что, если клиент захочет добавить в пиццу картофель фри? Списки и операторы if позволят вам убедиться в том, что входные данные имеют смысл, прежде чем обрабатывать их.

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

available_toppings = ['mushrooms', 'olives', 'green peppers',

                      'pepperoni', 'pineapple', 'extra cheese']

 

❶ requested_toppings = ['mushrooms', 'french fries', 'extra cheese']

 

for requested_topping in requested_toppings:

❷     if requested_topping in available_toppings:

        print(f"Adding {requested_topping}.")

❸     else:

        print(f"Sorry, we don't have {requested_topping}.")

 

print("\nFinished making your pizza!")

Сначала определяется список доступных начинок. Стоит заметить, что если в пиццерии используется постоянный ассортимент начинок, то список можно реа­лизовать в виде кортежа. Затем создается список начинок, заказанных клиентом. Обратите внимание на необычный заказ 'french fries' . Далее программа перебирает список заказанных начинок. Внутри цикла она сначала проверяет, что каждая заказанная начинка есть в списке доступных начинок . Если начинка доступна, то добавляется в пиццу. Если заказанная начинка не входит в список, то выполняется блок else . Этот блок выводит сообщение о том, что начинка недоступна.

Благодаря этому синтаксису программа выдает четкий, содержательный вывод:

Adding mushrooms.

Sorry, we don't have french fries.

Adding extra cheese.

 

Finished making your pizza!

Всего в нескольких строках кода нам удалось эффективно решить вполне реальную проблему!

Упражнения

5.8. Здравствуйте, админ! Создайте список из пяти и более имен пользователей, содержащий имя 'admin'. Представьте, что пишете код, который выводит приветственное сообщение для каждого пользователя после его входа на сайт. Переберите элементы списка и выведите сообщение для каждого пользователя:

 для пользователя 'admin' выведите особое сообщение: например, «Здравствуйте, admin, хотите просмотреть отчет о состоянии дел?»;

 в остальных случаях выводите универсальное приветствие: например, «Привет, Денис, спасибо, что авторизовался в системе».

5.9. Нет пользователей. Добавьте в программу hello_admin.py оператор if, который проверит, что список пользователей не пуст.

 Если список пуст, то выведите сообщение «Нам нужно добавить несколько пользователей!»

 Удалите из списка все имена пользователей и убедитесь в том, что программа выводит правильное сообщение.

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

 Создайте список current_users, содержащий пять и более имен пользователей.

 Создайте список new_users, содержащий пять имен пользователей. Убедитесь в том, что одно или два новых имени также присутствуют в списке current_users.

 Переберите список new_users и проверьте, было ли использовано ранее каждое имя в этом списке. Если да, то выведите сообщение о том, что пользователь должен выбрать новое имя. Если нет, то выведите сообщение о доступности имени.

 Проследите за тем, чтобы сравнение выполнялось без учета регистра символов. Если имя 'John' уже используется, то в регистрации имени 'JOHN' следует отказать. (Для этого необходимо создать копию current_users, содержащую версию всех существующих имен пользователей, написанных в нижнем регистре.)

5.11. Порядковые числительные. Порядковые числительные в английском языке заканчиваются суффиксом th (кроме 1st, 2nd и 3rd).

 Сохраните числа от 1 до 9 в списке.

 Переберите элементы списка.

 Используйте цепочку if-elif-else в цикле для вывода правильного окончания числительного для каждого числа. Программа должна выводить числительные "1st 2nd 3rd 4th 5th 6th 7th 8th 9th", причем каждый результат должен располагаться на отдельной строке.

Оформление операторов if

Во всех примерах этой главы применялись правила форматирования. В PEP 8 приведена только одна рекомендация, касающаяся проверки условий: до и после операторов сравнения (такие как ==, >=, <= и т.д.) ставить одиночные пробелы. Например, запись

if age < 4:

лучше, чем:

if age<4:

Пробелы не влияют на интерпретацию вашего кода Python; они только упрощают чтение кода для вас и других разработчиков.

Упражнения

5.12. Форматирование операторов if. Проанализируйте программы, написанные в этой главе, и проверьте, правильно ли вы оформляли проверку условий.

5.13. Ваши идеи. К этому моменту вы уже стали более квалифицированным программистом, чем когда начинали читать эту книгу. Теперь вы лучше представляете, как в программах моделируются явления реального мира, и сможете придумать задачи, которые будут решаться в ваших программах. Запишите несколько задач, которые вам хотелось бы решить по мере роста вашего профессионального мастерства. Может быть, это какие-то компьютерные игры, задачи анализа наборов данных или веб-приложения?

Резюме

В этой главе вы научились писать условия, результатом которых всегда является логическое значение (True или False). Вы узнали, как писать простые операторы if, а также цепочки if-else и if-elif-else. Вы начали использовать эти структуры для выявления конкретных условий, которые необходимо проверить, и собственно проверки этих условий в ваших программах. Вы научились обрабатывать определенные элементы списка иначе, чем остальные, сохраняя эффективность циклов for. Кроме того, вы узнали новые рекомендации по форматированию кода Python, которые упрощают чтение и понимание более сложных программ.

В главе 6 вы познакомитесь со словарями Python. Словарь отчасти напоминает список, но позволяет связывать разные виды информации. Вы научитесь создавать словари, перебирать их элементы, использовать их в сочетании со списками и операторами if. Словари помогут вам моделировать еще больше реальных ситуаций.

Назад: 4. Работа со списками
Дальше: 6. Словари