6 .2 . Осмысление включений
205
Циклы
for
в Python в действительности являются циклами «for each»,
которые могут напрямую перебирать элементы контейнера или по-
следовательности.
6 .2 . Осмысление
включений
Одно из моих любимых функциональных средств языка Python — вклю-
чения в список
1
. На первый взгляд эта конструкция может показаться
немного загадочной, но когда вы разложите ее по полочкам, она окажется
очень простой.
Ключ к пониманию конструкций включения в список состоит в том, что
они попросту являются циклами с обходом коллекции, выраженными при
помощи более сжатого и компактного синтаксиса.
Такие синтаксические конструкции, или синтаксический сахар, — неболь-
шая краткая форма для часто используемой функциональности, которая
делает нашу программистскую питоновскую жизнь легче. В качестве
примера возьмем приведенное ниже включение в список:
>>> squares = [x * x for x in range(10)]
В нем вычисляется квадрат всех чисел в списке от нуля до девяти:
>>> squares
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Если бы вы хотели построить тот же самый список, использовав обыкно-
венный цикл
for
, то вы,
вероятно, написали бы что-то типа этого:
>>> squares = []
>>> for x in range(10):
... squares.append(x * x)
1
Термин list comprehension также переводится не совсем удобным термином «списковое
включение». Дело в том, что в Python, помимо включения собственно в список, еще
существуют конструкции включения в словарь (dictionary comprehension) и включения
в множество (set comprehension). —
Примеч. пер.
206 Глава 6 • Циклы и итерации
Довольно-таки прямолинейный цикл, не правда ли? Если вы вернетесь
и сопоставите пример с включением в список и версию с циклом
for
,
то заметите общие черты, и в конечном счете у вас появятся некоторые
шаблоны. Обобщив здесь часть общей структуры, вы в итоге придете
к шаблону, похожему на следующий:
values = [expression for item in collection]
Приведенный выше «шаблон» включения в список эквивалентен пред-
ставленному
ниже обыкновенному циклу
for
:
values = []
for item in collection:
values.append(expression)
Здесь мы сначала настраиваем новый экземпляр списка
list
, который
получит выходные значения. Затем мы выполняем обход всех значений
в контейнере, преобразовывая каждый из них при помощи произволь-
ного выражения, и затем добавляем отдельные результаты в выходной
список.
Мы имеем типовой шаблон в стиле «формы для печенья», который вы
можете применять ко многим циклам
for
. Этот шаблон предназначен
для преобразования циклов в конструкцию включения в список, и на-
оборот. Нужно сказать, что есть еще одно полезное дополнение, которое
мы должны внести в этот шаблон, а именно — фильтрация элементов по
условиям.
Включения в список могут фильтровать значения, основываясь на некоем
произвольном условии, которое определяет, становится результирующее
значение частью выходного списка или нет. Приведем пример:
>>> even_squares = [x * x for x in range(10)
if x % 2 == 0]
Данное включение в список вычислит список квадратов всех четных
целых чисел от нуля до девяти. Использованный здесь оператор остатка
(
%
) возвращает остаток после деления одного числа на другое. В данном
6 .2 . Осмысление включений
207
примере мы его используем, чтобы проверить, является ли число четным.
И оно имеет требуемый результат:
>>> even_squares [0, 4, 16, 36, 64]
Новое включение в список может быть преобразовано в эквивалентный
цикл
for
аналогично первому примеру:
even_squares = [] for x in range(10):
if x % 2 == 0:
even_squares.append(x * x)
Давайте попробуем еще слегка обобщить указанный выше шаблон, где
включение в список трансформируется в цикл
for
. На этот раз мы соби-
раемся добавить в наш шаблон фильтрующее условие, которое определяет,
какие значения попадут в выходной список. Вот обновленный шаблон
включения в список:
values = [expression
for
item in collection
if condition]
И снова, это включение в список можно преобразовать в цикл
for
с по-
мощью следующего ниже шаблона:
values = [] for item in collection:
if condition:
values.append(expression)
В очередной раз это преобразование было прямолинейным — мы просто
применили обновленный типовой шаблон. Надеюсь, все это рассеяло
Do'stlaringiz bilan baham: