I think the documentation of functools.reduce(function, iterable[, initializer]) is quite readable. The iteration is carried out, applying the operation from left to right to consecutive elements and accumulating the result in the left operand. To be sure about the aspects in question, it helps to create variations of above code.
In the following example, we get the sum of the elements; we see that there is no implicit 1
as "default" value at work:
>>> print(reduce(lambda x, y: x + y, [2,3]))
5
The reduction stops if there are no elements left in the iterable:
>>> print(reduce(lambda x, y: x + y, [1]))
1
The reduction fails if there are no elements at all:
>>> print(reduce(lambda x, y: x + y, []))
Traceback (most recent call last):
File "<pyshell#11>", line 1, in <module>
print(reduce(lambda x, y: x + y, []))
TypeError: reduce() of empty sequence with no initial value
The optional initializer
value is used to start the reduction (and immediately stops it if there are no elements):
>>> print(reduce(lambda x, y: x + y, [], 0))
0
So x
is indeed the accumulator that is initialized with the optional initializer
value before entering the iterable. And y
is the next value from the iterable, if there are no elements (left), the function
is ignored.
Here another example to better understand the roles of x
and y
:
>>> print(reduce(lambda x, y: x - y, [1,2,3], 10))
4
In single-step mode, above reduction would look like this:
x = 10 # initializer
y = 1 # from iterable
x = x-y # x==9
y = 2 # from iterable
x = x-y # x==7
y = 3 # from iterable
x = x-y # x==4
4 # result