Python:我可以使用初始化程序部分应用 reduce 吗?
Python: Can I partially apply reduce with an initializer?
initializer
在 iterable
之后。这会导致部分应用程序出现问题。考虑这些(微不足道的)例子:
In [1]: from functools import reduce, partial
In [2]: f = partial(reduce, lambda a,b: a+b, 100)
In [3]: f([1,2,3])
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-3-816cce84b257> in <module>()
----> 1 f([1,2,3])
TypeError: reduce() arg 2 must support iteration
In [4]: f = partial(reduce, lambda a,b: a+b, initializer=100)
In [5]: f([1,2,3])
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-5-816cce84b257> in <module>()
----> 1 f([1,2,3])
TypeError: reduce() takes no keyword arguments
有什么技巧可以解决这个问题吗?
只需更改参数的顺序:
>>> f = partial(lambda func, init, iterable: reduce(func, iterable, init),
lambda a,b: a+b, 100)
>>> f([1,2,3])
106
Marat 给出了很好的解决方案。为了好玩,我写了 foldl
并翻转了参数。我很好奇这将如何比较 performance-wise 与使用 lambda 像 Marat 那样翻转参数。
def foldl(f: Callable, acc: Any, xs: Iterable) -> Any:
if not xs:
return acc
return foldl(f, f(acc, xs[0]), xs[1:])
initializer
在 iterable
之后。这会导致部分应用程序出现问题。考虑这些(微不足道的)例子:
In [1]: from functools import reduce, partial
In [2]: f = partial(reduce, lambda a,b: a+b, 100)
In [3]: f([1,2,3])
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-3-816cce84b257> in <module>()
----> 1 f([1,2,3])
TypeError: reduce() arg 2 must support iteration
In [4]: f = partial(reduce, lambda a,b: a+b, initializer=100)
In [5]: f([1,2,3])
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-5-816cce84b257> in <module>()
----> 1 f([1,2,3])
TypeError: reduce() takes no keyword arguments
有什么技巧可以解决这个问题吗?
只需更改参数的顺序:
>>> f = partial(lambda func, init, iterable: reduce(func, iterable, init),
lambda a,b: a+b, 100)
>>> f([1,2,3])
106
Marat 给出了很好的解决方案。为了好玩,我写了 foldl
并翻转了参数。我很好奇这将如何比较 performance-wise 与使用 lambda 像 Marat 那样翻转参数。
def foldl(f: Callable, acc: Any, xs: Iterable) -> Any:
if not xs:
return acc
return foldl(f, f(acc, xs[0]), xs[1:])