function namesScores(arr) {
// Good luck!
arr.sort();
return arr.reduce((acc, v, i) => acc + wordWorth(v) * (i + 1), 0);
}
Run Code Online (Sandbox Code Playgroud)
在上面用 javascript 编写的代码中,我赋予reduce 函数的可调用函数使用三个参数accumulator、currentItem、currentIndex。
from functools import reduce
def nameScores(arr):
arr.sort()
return reduce(lambda acc, v, i: acc + wordWorth(v) * (i + 1), arr, 0)
Run Code Online (Sandbox Code Playgroud)
在用 python 编写相同的代码时,我收到一个错误:
Traceback (most recent call last):
File "/home/cyogian/practicePython/ProjectEuler/p022/p022.py", line 22, in <module>
print(nameScores(test1))
File "/home/cyogian/practicePython/ProjectEuler/p022/p022.py", line 18, in nameScores
return reduce(lambda acc, v, i: acc + wordWorth(v) * (i + 1), arr, 0)
TypeError: <lambda>() missing 1 required positional argument: 'i'
Run Code Online (Sandbox Code Playgroud)
这表示 currentIndex 参数丢失。python functools中的reduce函数是否无法访问currentIndex?
python 中是否有其他版本的reduce 可以访问可迭代中当前项目的索引?
或者,在需要访问索引的情况下,我应该使用简单的 forLoop 吗?
您不需要特殊形式的reduce来访问索引:只需在enumerate要减少的可迭代对象上使用该函数即可。
>>> a = ['foo', 'bar', 'baz']
>>> from functools import reduce
>>> reduce(lambda acc, iv: acc + str(iv[0]) + iv[1], enumerate(a), '')
'0foo1bar2baz'
Run Code Online (Sandbox Code Playgroud)
这里,iv是 中的一对enumerate,iv[0]索引 是 ,iv[1]值 是 。
Python 中的函数reduce确实没有将索引传递给回调。JavascriptArray.reduce方法确实如此,并且可以摆脱这个问题,因为如果您传递的参数多于 Javascript 函数预期的参数,它们就会被忽略;所以 JavaScript 中的回调函数可以像这样,当它作为参数(acc, v) => acc + v调用时,它将忽略索引。(acc, v, i)
Python 函数不会默默地忽略额外的参数;如果你在 Python 中调用一个带有太多参数的函数,它会引发一个TypeError. 这意味着如果reduce使用参数调用回调函数(acc, v, i),那么您将需要提供一个接受索引的回调函数,即使在绝大多数情况下,您不需要使用索引来执行任何操作。也就是说,如果您可以reduce(lambda acc, v, i: ..., ..., ...)在回调函数采用三个参数的情况下进行调用,那么您始终必须像在 Python 中那样进行调用reduce。