How reduction works:
# type annotations: # reduce(lambda X,X:X, [X,X..]) -> X # SAME <-- result # ↗ ↖ # SAME SAME] # ↗ ↖ # SAME SAME, # ↗ ↖ # [SAME, SAME, >>> reduce(lambda a,b:[a,b], [1,2,3,4]) [[[1, 2], 3], 4]
Here's how seed reduction (aka fold-left) works:
# type annotations:
Do you want to:
maxValue,maxIndex = reduce( lambda p1,p2: max(p1,p2), ((x,i) for i,x in enumerate(yourList)) )
An important note about reduce
is the types . * When you use the abbreviation (...) with the initial value (called fold
in other languages), the return type will be the seed type. * When you usually use reduce
, it ignores the seed element. This works fine if all the elements in your list are of the same type (for example, you can reduce(operator.mul, [1,2,3])
or reduce(operator.add, [1,2,3])
just fine, because the reduced output type (int) is the same as the unrestored input type (two ints)). However, the return type will be the same as the type of the list item.
If your elements are of different types, you need to use reduce (...) in fold
-mode (i.e. with a seed with the correct semantics). (The alternative is a special case of your lambda (very ugly).)
More specifically, your intended return type is a tuple (the maximum element and its index, or reverse). However, your reduction function is of type tuple,tuple -> int
. This may not work, because it violates the contract, which reduces the requirements for your function.