I would expect the two to mean the same, from a functional equational standpoint, however:
x = [1, 2, 3]
y = ['a', 'b', 'c']
reduce(lambda x, y: x + y, zip(x, y)) # works
sum(zip(x, y)) # fails
Why is sum
failing here?
The actual problem is, with the sum
's default start value. Quoting the documentation ,
Sums start and the items of an iterable from left to right and returns the total. start defaults to
0
. The iterable's items are normally numbers, and the start value is not allowed to be a string.
But, in case of reduce
, if no optional start value is given, it will use the first value in the iterable as the initializer. So, reduce
is actually evaluating it like this
( ( (1, 'a') + (2, 'b') ) + (3, 'c') )
Since sum
assumes start value as 0, it evaluates it like this,
0 + (1, 'a') + (2, 'b') + (3, 'c')
In this case, it tries to add 0
with a tuple and that is why you are getting
TypeError: unsupported operand type(s) for +: 'int' and 'tuple'
To fix this, pass an empty tuple, to sum
's start, like this
>>> sum(zip(x, y), tuple())
(1, 'a', 2, 'b', 3, 'c')
Now, with the initial value being an empty tuple, the evaluation happens like this
() + (1, 'a') + (2, 'b') + (3, 'c')
Note: In both these case, there will be more than one intermediate tuples created. To avoid that, I would recommend flattening the data and pass it to tuple
constructor as a generator expression, like this
>>> tuple(item for items in zip(x, y) for item in items)
(1, 'a', 2, 'b', 3, 'c')
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.