我认为您要做的是做一个递归版本的reduce。
def rreduce(f, init, default=None):
if default is None:
default = init[0]
init = init[1:]
if len(init) == 0:
return default
return rreduce(f, init[1:], f(default, init[0]))
>>> rreduce(lambda a, b: a*b, range(1,10))
362880
>>> rreduce(lambda a, b: a+b, ['t', 'a', 'c', 'o'])
'taco'
虽然递归很棒,但这不是 Python 中 reduce 类型函数的首选方式,因为它很慢而且你会遇到 STACK OVERFLOW (HAA)
>>> rreduce(lambda a, b: a + [b], list(range(1, 10000)), [])
---------------------------------------------------------------------------
RecursionError Traceback (most recent call last)
<ipython-input-41-7dc07c5d9246> in <module>()
----> 1 rreduce(lambda a, b: a + [b], list(range(1, 10000)), [])
<ipython-input-33-37206eb8e39f> in rreduce(f, init, default)
5 if len(init) == 0:
6 return default
----> 7 return rreduce(f, init[1:], f(default, init[0]))
... last 1 frames repeated, from the frame below ...
<ipython-input-33-37206eb8e39f> in rreduce(f, init, default)
5 if len(init) == 0:
6 return default
----> 7 return rreduce(f, init[1:], f(default, init[0]))
RecursionError: maximum recursion depth exceeded in comparison
回答您的实际问题...
def lreduce(f, init, default=None):
if default is None:
return reduce(lambda x, a: x + [reduce(f, a)], init, [])
else:
return reduce(lambda x, a: x + [reduce(f, a, default)], init, [])
将reduce 列表列表。
>>> lreduce(lambda a, b: a + b, [range(10), range(10), range(10)])
[45, 45, 45]
if/else 之所以必要是因为reduce 作为builtin 不接受关键字参数:
In [56]: reduce(function=lambda a, b: a + b, sequence=range(10), initial=0)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-56-9fa3ed177831> in <module>()
----> 1 reduce(function=lambda a, b: a + b, sequence=range(10), initial=0)
TypeError: reduce() takes no keyword arguments
然后如果你想更进一步......
def lreduceall(f, init, default=None):
if default is None:
return reduce(f, reduce(lambda x, a: x + [reduce(f, a)], init, []))
else:
return reduce(f, reduce(lambda x, a: x + [reduce(f, a, default)], init, []), default)
终于:
>>> lreduceall(lambda a, b: a + b, [range(10), range(10), range(10)])
135