воскресенье, 1 декабря 2019 г.

ЛМНты Python, 31 - 35

>>> map и filter

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

Функция, передаваемая в map, отображает входное значение на другое. Например:

>>> def cube(n):
...     return n**3
...
>>> m = map(cube, [1, 2, 3, 4])
>>> type(m)
<class 'map'>
>>> list(m)
[1, 8, 27, 64]

Функция для filter проверяет, удовлетворяет ли входное значение некоторому условию и возвращает True или False (или другой объект, который будет интерпретирован как True или False ):

>>> def odd(n):
...     return n%2
...
>>> f = filter(odd, [1, 2, 3, 4])
>>> type(f)
<class 'filter'>
>>> list(f)
[1, 3]

>>> Лямбда-функции

Лямбда-функции – это безымянные функции, отображающие одно значение на другое, и предназначенные для передачи в качестве аргумента при вызове функции. Например:

>>> seq = [1, 2, 3, 4]
>>>
>>> m = map(lambda x: x**3, seq)
>>> list(m)
[1, 8, 27, 64]
>>>
>>> f = filter(lambda x: x%2, seq)
>>> list(f)
[1, 3]

Лямбда-функцию можно присвоить некоторому имени, но это не будет полноценной заменой функции, определенной с помощью def. Посмотрите на атрибут __name__ (важный для анализа кода и интроспекции):

>>> add = lambda a,b: a+b
>>> add(2, 7)
9
>>> add.__name__
'<lambda>'
>>>
>>> def add(a, b): return a+b
...
>>> add.__name__
'add'
>>> add2 = add
>>> add2.__name__
'add'

Полноценные функции помнят свое имя, а лямбда-функции анонимны.

>>> reduce

В модуле functools имеется функция reduce, которая "агрегирует" элементы последовательности в одно значение. Функция, передаваемая в reduce, принимает два аргумента: аккумулятор, в котором накапливается результат, и очередной элемент последовательности. Пример расчета произведения элементов списка:

>>> from functools import reduce
>>> seq = [1, 2, 3, 4]
>>> reduce(lambda a, x: a*x, seq)
24

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

>>> a, b = reduce(
...     lambda a, x: (a[0]*x, a[1]+x),
...     seq,
...     (1, 0)
... )
>>> a
24
>>> b
10

>>> sum и join

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

>>> seq = [1, 2, 3, 4]
>>> sum(seq)
10
>>> sum(range(5))
10
>>> sum(seq, 10)
20

Для суммирования (конкатенации) последовательности строк имеется строковый метод join:

>>> '.'.join('hello')
'h.e.l.l.o'
>>> '+'.join(['hello', 'world'])
'hello+world'

>>> Как reduce

Кроме reduce и sum имеются другие функции, приводящие элементы последовательности или итерируемого объекта к единственному значению:

>>> seq = [1, 2, 3, 4]
>>> min(seq)
1
>>> max('hello')
'o'
>>> any('hello')
True
>>> all(range(5))
False

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

>>> any(map(lambda x: x>3, seq))
True
>>> any(map(lambda x: x<1, seq))
False
>>> all(map(lambda x: x>3, seq))
False

Здесь map отображает исходную последовательность на булеву последовательность.

Комментариев нет:

Отправить комментарий