Например, в следующем фрагменте кода можно избавится от символов, которые не являются буквами:
>>> filter(lambda x: x.isalpha(), 'Hi, there! I am eating an apple.')
'HithereIameatinganapple'
Списковые включения
Для более естественной записи обработки списков в Python 2 была внесена новинка: списковые включения. Фактически это специальный сокращенный синтаксис для вложенных циклов for
и условий if
, на самом низком уровне которых определенное выражение добавляется к списку, например:
all_pairs = []
for i in range(5):
for j in range(5):
if i <= j:
all_pairs.append((i, j))
Все это можно записать в виде спискового включения так:
all_pairs = [(i, j) for i in range(5) for j in range(5) if i <= j]
Как легко заметить, списковые включения позволяют заменить map()
и filter()
на более удобные для прочтения конструкции.
В следующей таблице приведены эквивалентные выражения в разных формах:
В форме функции | В форме спискового включения |
---|---|
filter(f, lst) | [x for x in lst if f(x)] |
filter(None, lst) | [x for x in lst if x] |
map(f, lst) | [f(x) for x in lst] |
Функция sum()
Получить сумму элементов можно с помощью функции sum()
:
>>> sum(range(10))
45
Эта функция работает только для числовых типов, она не может конкатенировать строки. Для конкатенации списка строк следует использовать метод join()
.
Функция reduce()
Для организации цепочечных вычислений (вычислений с накоплением результата) можно применять функцию reduce()
, которая принимает три аргумента: функцию двух аргументов, последовательность и начальное значение. С помощью этой функции можно, в частности, реализовать функцию sum()
:
def sum(lst, start):
return reduce(lambda x, y: x + y, lst, start)
Следует помнить, что в качестве передаваемого объекта может оказаться список, который позволит накапливать промежуточные результаты. Тем самым, reduce()
может использоваться для генерации последовательностей.
В следующем примере накапливаются промежуточные результаты суммирования:
lst = range(10)
f = lambda x, y: (x[0] + y, x[1]+[x[0] + y])
print reduce(f, lst, (0, []))
В итоге получается:
(45, [0, 1, 3, 6, 10, 15, 21, 28, 36, 45])
Функция zip()
Эта функция возвращает список кортежей, в котором i
–й кортеж содержит i
–е элементы аргументов–последовательностей. Длина результирующей последовательности равна длине самой короткой из последовательностей–аргументов:
>>> print zip(range(5), "abcde")
[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd'), (4, 'e')]
Итераторы
Применять для обработки данных явные последовательности не всегда эффективно, так как на хранение временных данных может тратиться много оперативной памяти. Более эффективным решением представляется использование итераторов — специальных объектов, обеспечивающих последовательный доступ к данным контейнера. Если в выражении есть операции с итераторами вместо контейнеров, промежуточные данные не будут требовать много места для хранения — ведь они запрашиваются по мере необходимости для вычислений. При обработке данных с использованием итераторов память будет требоваться только для исходных данных и результата, да и то необязательно вся сразу — ведь данные могут читаться и записываться в файл на диске.
Итераторы можно применять вместо последовательности в операторе for
. Более того, внутренне оператор for
запрашивает от последовательности ее итератор. Объект файлового типа тоже (построчный) итератор, что позволяет обрабатывать большие файлы, не считывая их целиком в память.
Там, где требуется итератор, можно использовать последовательность.
Работа с итераторами рассматривается в разделе, посвященном функциональному программированию, так как итераторами удобно манипулировать именно в функциональном стиле.