How reduce 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]
This is how reduce with a seed (a.k.a. fold-left) works:
# type annotations:
# reduce(lambda REDU,ELEM:REDU, [ELEM,ELEM..], seed=REDU) -> REDU
# REDU <-- result
# ↗ ↖
# REDU ELEM]
# ↗ ↖
# REDU ELEM,
# ↗ ↖
# REDU ELEM,
# ↗ ↖
# REDU [ELEM,
>>> reduce(lambda a,b:[a,b], [1,2,3,4], 'seed')
[[[['seed', 1], 2], 3], 4]
You want:
maxValue,maxIndex = reduce(
lambda p1,p2: max(p1,p2),
((x,i) for i,x in enumerate(yourList))
)
The important thing to notice about reduce is the types.
* When you use reduce(...) with a seed value (known as fold in other languages), the return type will be the seed's type.
* When you use reduce normally, it ignores the seed element. This works great if all elements of your list are 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 unreduced input type (two ints)). However the return type will be the same as the list's element's type.
If your elements are of different types, you need to use reduce(...) in fold-mode (i.e. with a seed with the right semantics). (The alternative is to special-case your lambda (very ugly).)
More explicitly, your intended return type is a tuple (the max element and its index, or the reverse). However your reduction function is of type tuple,tuple -> int. This cannot work because it violates the contract that reduce demands of your function.