Простой Python — страница 13 из 66

>>> some_list = []

>>> if some_list:

…·····print("There's something in here")

… else:

…·····print("Hey, it's empty!")

Hey, it's empty!

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

if color == "red":

Python оценит выражение color == "red". В нашем примере мы присвоили переменной color значение "puce", поэтому значение выражения color == "red" равно False и Python перейдет к следующей проверке:

elif color == "green":

Повторяем действия с помощью while

Проверки с помощью if, elif и else выполняются последовательно. Иногда нам нужно выполнить какие-то операции более чем один раз. Нам нужен цикл, и простейшим вариантом циклов в Python является while. Попробуйте запустить с помощью интерактивного интерпретатора следующий пример — это простейший цикл, который выводит на экран значения от 1 до 5:

>>> count = 1

>>> while count <= 5:

…·····print(count)

…·····count += 1

1

2

3

4

5

>>>

Сначала мы присваиваем значение 1 переменной count. Цикл while сравнивает значение переменной count с числом 5 и продолжает работу, если значение переменной count меньше или равно 5. Внутри цикла мы выводим значение переменной count, а затем увеличиваем его на 1 с помощью выражения count += 1. Python возвращается к верхушке цикла и снова сравнивает значение переменной count с числом 5. Значение переменной count теперь равно 2, поэтому содержимое цикла while выполняется снова и переменная count увеличивается до 3.

Это продолжается до тех пор, пока переменная count не будет увеличена с 5 до 6 в нижней части цикла. Во время очередного возврата наверх цикла проверка count <= 5 вернет значение False и цикл while закончится. Python перейдет к выполнению следующих строк.

Прерываем цикл с помощью break

Если вы хотите, чтобы цикл выполнялся до тех пор, пока что-то не произойдет, но вы не знаете точно, когда это событие случится, можете воспользоваться бесконечным циклом, содержащим оператор break. В этот раз мы считаем строку с клавиатуры с помощью функции input(), а затем выведем ее на экран, сделав первую букву прописной. Мы прервем цикл, когда будет введена строка, содержащая только букву «q»:

>>> while True:

…·····stuff = input("String to capitalize [type q to quit]: ")

…·····if stuff == "q":

…·········break

…·····print(stuff.capitalize())

String to capitalize [type q to quit]: test

Test

String to capitalize [type q to quit]: hey, it works

Hey, it works

String to capitalize [type q to quit]: q

>>>

Пропускаем итерации с помощью continue

Иногда вам нужно не прерывать весь цикл, а только пропустить по какой-то причине одну итерацию. Рассмотрим воображаемый пример: считаем целое число, выведем на экран его значение в квадрате, если оно четное, и пропустим его, если оно нечетное. Мы даже добавим несколько комментариев. И вновь для выхода из цикла используем строку "q":

>>> while True:

…·····value = input("Integer, please [q to quit]: ")

…·····if value == 'q':······# выход

…·········break

…·····number = int(value)

…·····if number % 2 == 0:···# нечетное число

…········continue

…·····print(number, "squared is", number*number)

Integer, please [q to quit]: 1

1 squared is 1

Integer, please [q to quit]: 2

Integer, please [q to quit]: 3

3 squared is 9

Integer, please [q to quit]: 4

Integer, please [q to quit]: 5

5 squared is 25

Integer, please [q to quit]: q

>>>

Проверяем, завершился ли цикл заранее, с помощью else

Если цикл while завершился нормально (без вызова break), управление передается в опциональный блок else. Вы можете использовать его в цикле, где выполняете некоторую проверку и прерываете цикл, как только проверка успешно выполняется. Блок else выполнится в том случае, если цикл while будет пройден полностью, но искомый объект не будет найден:

>>> numbers = [1, 3, 5]

>>> position = 0

>>> while position < len(numbers):

…·····number = numbers[position]

…·····if number % 2 == 0:

…·········print('Found even number', number)

…·········break

…·····position += 1

… else:··# break not called

…·····print('No even number found')

No even number found


Такое использование ключевого слова else может оказаться нелогичным. Рассматривайте его как проверку на прерывание цикла.

Выполняем итерации с помощью for

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

Вполне возможно пройти по последовательности таким образом:

>>> rabbits = ['Flopsy', 'Mopsy', 'Cottontail', 'Peter']

>>> current = 0

>>> while current < len(rabbits):

…·····print(rabbits[current])

…·····current += 1

Flopsy

Mopsy

Cottontail

Peter

Однако существует более характерный для Python способ решения этой задачи:

>>> for rabbit in rabbits:

…·····print(rabbit)

Flopsy

Mopsy

Cottontail

Peter

Списки вроде rabbits являются одними из итерабельных объектов в Python наряду со строками, кортежами, словарями и некоторыми другими элементами. Итерирование по кортежу или списку возвращает один элемент за раз. Итерирование по строке возвращает один символ за раз, как показано здесь:

>>> word = 'cat'

>>> for letter in word:

…·····print(letter)

c

a

t

Итерирование по словарю (или его функции keys()) возвращает ключи. В этом примере ключи являются типами карт в настольной игре Clue (за пределами Северной Америки она называется CluedoAmerica):

>>> accusation = {'room': 'ballroom', 'weapon': 'lead pipe',

··················'person': 'Col. Mustard'}

>>> for card in accusation:··#··или for card in accusation.keys():

…·····print(card)

room

weapon

person

Чтобы итерировать по значениям, а не по ключам, следует использовать функцию values():

>>> for value in accusation.values():

…·····print(value)

ballroom

lead pipe

Col. Mustard

Чтобы вернуть как ключ, так и значение кортежа, вы можете использовать функцию items():

>>> for item in accusation.items():

…·····print(item)

('room', 'ballroom')

('weapon', 'lead pipe')

('person', 'Col. Mustard')

Помните, что можете присвоить значение кортежу за один шаг. Для каждого кортежа, возвращенного функцией items(), присвойте первое значение (ключ) переменной card, а второе (значение) — переменной contents:

>>> for card, contents in accusation.items():

…·····print('Card', card, 'has the contents', contents)

Card weapon has the contents lead pipe

Card person has the contents Col. Mustard

Card room has the contents ballroom

Прерываем цикл с помощью break

Ключевое слово break в цикле for прерывает этот цикл точно так же, как и цикл while.

Пропускаем итерации с помощью continue

Добавление ключевого слова continue в цикл for позволяет перейти на следующую итерацию цикла, как и в случае с циклом while.

Проверяем, завершился ли цикл заранее, с помощью else

Как и в цикле while, в for имеется опциональный блок else, который проверяет, выполнился ли цикл for полностью. Если ключевое слово break не было вызвано, будет выполнен блок else.

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

>>> cheeses = []

>>> for cheese in cheeses:

…·····print('This shop has some lovely', cheese)

…·····break

… else:··# отсутствие прерывания означает, что сыра нет

…·····print('This is not much of a cheese shop, is it?')

This is not much of a cheese shop, is it?


Как и в цикле while, в цикле for использование блока else может показаться нелогичным. Можно рассматривать цикл for как поиск чего-то, в таком случае else будет вызываться, если вы ничего не нашли. Чтобы получить тот же эффект без блока else, используйте переменную, которая будет показывать, нашелся ли искомый элемент в цикле for, как здесь:

>>> cheeses = []

>>> found_one = False

>>> for cheese in cheeses:

…·····found_one = True

…·····print('This shop has some lovely', cheese)

…·····break

>>> if not found_one:

…·····print('This is not much of a cheese shop, is it?')

This is not much of a cheese shop, is it?

Итерирование по нескольким последовательностям с помощью функции zip()

Существует еще один полезный прием — параллельное итерирование по нескольким последовательностям с помощью функции zip():

>>> days = ['Monday', 'Tuesday', 'Wednesday']

>>> fruits = ['banana', 'orange', 'peach']

>>> drinks = ['coffee', 'tea', 'beer']

>>> desserts = ['tiramisu', 'ice cream', 'pie', 'pudding']

>>> for day, fruit, drink, dessert in zip(days, fruits, drinks, desserts):

…·····print(day, ": drink", drink, "eat", fruit, "enjoy", dessert)

Monday: drink coffee — eat banana — enjoy tiramisu

Tuesday: drink tea — eat orange — enjoy ice cream

Wednesday: drink beer — eat peach — enjoy pie

Функция zip() прекращает свою работу, когда выполняется самая короткая последовательность. Один из списков (desserts) оказался длиннее остальных, поэтому никто не получит пудинг, пока мы не увеличим остальные списки.

В разделе «Словари» главы 3 показывается, как с помощью функции dict() можно создавать словари из последовательностей, содержащих два элемента, вроде кортежей, списков или строк. Вы можете использовать функцию zip(), чтобы пройти по нескольким последовательностям и создать кортежи из элементов с одинаковыми смещениями. Создадим два кортежа из соответствующих друг другу английских и французских слов:

>>> english = 'Monday', 'Tuesday', 'Wednesday'

>>> french = 'Lundi', 'Mardi', 'Mercredi'

Теперь используем функцию zip(), чтобы объединить эти кортежи в пару. Значение, возвращаемое функцией zip(), само по себе не является списком или кортежем, но его можно преобразовать в любую из этих последовательностей:

>>> list(zip(english, french))

[('Monday', 'Lundi'), ('Tuesday', 'Mardi'), ('Wednesday', 'Mercredi')]

Передайте результат работы функции zip() непосредственно функции dict() — и у нас готов небольшой англо-французский словарь!

>>> dict(zip(english, french))

{'Monday': 'Lundi', 'Tuesday': 'Mardi', 'Wednesday': 'Mercredi'}

Генерирование числовых последовательностей с помощью функции range()

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

Вы можете применять функцию range() аналогично slice(): range(start, stop, step). Если опустите значение start, диапазон начнется с 0. Необходимым является лишь значение stop: как и в случае со slice(), оно определяет последнее значение, которое будет создано прямо перед остановкой функции. Значение по умолчанию step равно 1, но вы можете изменить его на -1.

Как и zip(), функция range() возвращает итерабельный объект, поэтому вам нужно пройти по значениям с помощью конструкции for … in или преобразовать объект в последовательность вроде списка. Создадим диапазон 0, 1, 2:

>>> for x in range(0,3):

…·····print(x)

0

1

2

>>> list(range(0, 3))

[0, 1, 2]

Вот так можно создать диапазон от 2 до 0:

>>> for x in range(2, -1, -1):

…·····print(x)

2

1

0

>>> list(range(2, -1, -1))

[2, 1, 0]

В следующем фрагменте кода используется шаг 2, чтобы получить все четные числа от 0 до 10:

>>> list(range(0, 11, 2))

[0, 2, 4, 6, 8, 10]

Прочие итераторы

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

Включения