Приведение списка к единственному значению (Reduce)

borntohack

змееуст
Команда форума
Модератор
Апр 22, 2020
78
62
18
39
Москва, РФ
ПРИВЕДЕНИЕ СПИСКА К ЕДИНСТВЕННОМУ ЗНАЧЕНИЮ (Функция REDUCE)

Иногда мы хотим "схлопнуть" список каким-то таким образом, чтобы в результате иметь лишь одну величину.
Например, просуммировать все элементы списка, или перемножить их.
Подобную задачу решает функция reduce, правда она является уже частью библиотеки functools, которая, к счастью, включена в стандартную библиотеку python

Функция reduce принимает первым аргументом функцию (callable объект), которая принимает первыми двумя аргументами элементы списка, которые она должна преобразовать в один. Преобразование происходит слева направо. После преобразования первых двух элементов, функция будет считать свой результат левым элементом, а третий элемент - правым, и повторится вновь. Так будет происходить до тех пор, пока весь список не "схлопнется" до одного элемента.

Рассмотрим на примере:
Допустим, у нас есть список [2,8,4,6] и мы хотим его перемножить.
В первую очередь нужно импортировать функцию reduce:
Python:
from functools import reduce
Теперь обозначим функцию "схлапывания":
Python:
def mul(x,y):
    return x*y
Теперь "схлопнем" список:
Python:
lst = [2,8,4,6]
result = reduce(mul,lst)
В нашу переменную result запишется значение - результат умножения всех элементов списка: 384.

Обратите внимание, что, в отличие от map и filter - функция reduce возвращает итоговое значение, а не итерируемый объект. Так происходит, потому что reduce вычисляет значение по итерируемому списку, а не преобразовывает его.
Для понимания того, что сделал reduce - пошагово список получался таким:
В первой итерации на входе было [2,8,4,6], reduce передал в функцию mul первые два элемента списка: mul(2,8) и получил результат 16. Этот результат reduce поставил вместо этих двух элементов списка.
Во второй итерации на входе было уже [16,4,6] - reduce так же взял первые два элемента и отправил их в mul: mul(16,4) и получил результат 64. Этот результат reduce поставил вместо первых двух элементов. Теперь список стал быть [64,6]
Ну и в третьей итерации выполнилась та же операция с оставшимися двумя элементами: mul(64,6) -> 384. Поскольку больше элементов не осталось - reduce вернул нам это значение.
Тот же результат для понимания: (((2*8)*4)*6)=384
 

Форум IT Специалистов