Input in second code snippet is single element list - it's a degenerated case where callable isn't even called.
Consider following example:
def my_sum(*args):
print "my_sum called with", args
return sum(*args)
x = [1, 2, 3]
reduce(my_sum, [b for b in x if b > 2])
# nothing gets printed, value 3 is returned, since it's only element in list
Now consider your failed case:
reduce(my_sum, [b for b in x if b > 0])
Output is:
my_sum called with (1, 2)
[exception traceback]
Equivalent call to builtin sum is sum(1, 2), which results in same exception as quoted by you.
sum signature does not follow rules for reduce function. sum(iterable[, start]) takes two arguments (as expected), but first of them has to be iterable, where second is optional initial value.
reduce requires function to take two arguments, where (quoting docs):
The left argument, x, is the accumulated value and the right argument,
y, is the update value from the iterable.
We can clearly see that these interfaces are not conform with each other. Correct callable will be something like:
def reduce_sum(accumulator, new_value):
return accumulator + new_value
reduce(reduce_sum, [b for b in x if b > 0])
filter, that list comprehension is unnecessarily verbose