Itertools.accumulate() по сравнению с functools.reduce()
В Python 3.3 itertools.accumulate()
, который обычно многократно применяет операцию добавления к предоставленной итерации, теперь может принимать аргумент функции в качестве параметра; это означает, что теперь он перекрывается с functools.reduce()
. При поверхностном взгляде основные различия между ними теперь выглядят так:
accumulate()
по умолчанию суммирует, но не позволяет вам явно указать дополнительное начальное условие, в то время как reduce()
не использует по умолчанию какой-либо метод, но позволяет вам задать начальное условие для использования с последовательностями 1/0-элемента, и
accumulate()
выполняет итерацию первым, а reduce()
- функцию первой.
Есть ли другие различия между ними? Или это просто вопрос поведения двух функций с изначально различными видами использования, которые начинают сходиться со временем?
Ответы
Ответ 1
Похоже, что accumulate
сохраняет предыдущие результаты, тогда как reduce
(который в других языках известен как сворачивание) не обязательно.
например list(accumulate([1,2,3], operator.add))
вернет [1,3,6]
, тогда как простой фолд вернет 6
Также (просто для удовольствия, не делайте этого) вы можете определить accumulate
в терминах reduce
def accumulate(xs, f):
return reduce(lambda a, x: a + [f(a[-1], x)], xs[1:], [xs[0]])
Ответ 2
В документации вы можете видеть, в чем разница. reduce
возвращает один результат, сумму, произведение и т.д. последовательности. accumulate
возвращает итератор по всем промежуточным результатам. В принципе, accumulate
возвращает итератор по результатам каждого шага операции reduce
.
Ответ 3
itertools.accumulate
как reduce
, но возвращает генератор * вместо значения. Этот генератор может дать вам все промежуточные значения шага. Таким образом, в основном сокращение дает вам последний элемент того, что накопление даст вам.
* Генератор похож на итератор, но может повторяться только один раз.