python - python sum(list) 和 reduce(lambda x, y : x+y, list) 之间的差异?

标签 python python-2.7 list sum reduce

sum(list)reduce(lambda total , element : total + element, list) 有什么区别

orderItemsMap  = [149.94, 250.0, 199.99, 249.9, 149.94]

>>> sum(orderItemsMap)

999.77

orderItemsRevenue = reduce(lambda total , element : total +element , orderItemsMap)

>>>orderItemsRevenue

999.77

最佳答案

sum 更清楚地表达了您的意图,也更短了。

阅读 reduce 版本,我可以看到您正在使用某些功能减少列表。然后我读了那个函数,看到它正在添加值。所以,我可以弄清楚你在总结数字。然后我可能还需要验证您是否正确实现了它。

阅读 sum 版本,我立即知道您在对数字求和,而且做对了。


sum 更快。​​

In [905]: %timeit sum(orderItemsMap)
173 ns ± 3.13 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
In [906]: %timeit reduce(lambda total , element : total +element , orderItemsMap)
601 ns ± 8.09 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

reduce 版本必须做一个通用循环,而 sum 版本可以做一些优化。此外,reduce 版本必须为每一对值调用您的 lambda,而 sum 版本可以直接跳转到 __add__。而且,至少在 CPython 中,sum 对小整数求和有进一步的优化。


sum 适用于空列表。

In [907]: sum([])
Out[907]: 0
In [908]: reduce(lambda total , element : total +element, [])
TypeError: reduce() of empty sequence with no initial value 

当然,您可以通过添加第三个参数使 reduce 对空列表起作用:

In [909]: reduce(lambda total , element : total +element, [], 0)
Out[909]: 0

…但这使它变得更长,更不明显。


sum 阻止您意外地做您不想做的事情。

In [911]: sum(["abc", "def", "ghi"])
TypeError: unsupported operand type(s) for +: 'int' and 'str'
In [912]: sum(["abc", "def", "ghi"], '')
TypeError: sum() can't sum strings [use ''.join(seq) instead]
In [913]: reduce(lambda total , element : total +element, ["abc", "def", "ghi"])
Out[913]: 'abcdefghi'

使用 reduce,我只是连接了一堆字符串,这可能需要二次方时间,而我真正想做的是调用 ''.join,这需要线性时间。

好吧,CPython 3.7 和 PyPy 3.5/6.0 碰巧优化了这种情况,使其变得更好……但他们并没有这样做,比如说,一个元组列表。


sum 不会让 Guido 哭。

许多 Python 开发人员讨厌 reduce。通常的引述是“在每个 reduce 中,都有一个 for 循环正在努力退出”。或者 SyntaxError('Lisp 需要更多括号')

我认为这有点极端,而且我知道我不是唯一一个在 Python 中发现 reduce 很好用的人(其他核心开发人员不会有说服 Guido 将其移动到 functools 而不是在 3.0 中将其删除,否则……),但它确实会引发一个标志,让我更仔细地查看我的代码(或其他人的),看看是否有更 Pythonic 的方式来编写它,而且经常有。


reduce 可以做除求和之外的事情。

例如,假设您想从一堆数字中创建一个数字:

def fromdigits(*digits, base):
    return reduce(lambda acc, digit: base*acc + digit), digits, 0)

尝试用 sum 来写。

(虽然我敢打赌这个例子让 Guido 哭了,但第一个想到的不是关于树的……)

关于python - python sum(list) 和 reduce(lambda x, y : x+y, list) 之间的差异?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51717509/

相关文章:

python - 如何将字典列表转换为....?

python - 在 python 中发送 header

list - 列表中的 Javaslang/Vavr LinkedHashMap

python - 为什么 dict 没有在 python 多处理中更新?

python - 动态访问嵌套字典键?

python-2.7 - 如何在python中关闭文件描述符?

python - 使用 svgwrite-1.1.9 翻转输出

C# - 查找两个 List<T> 的共同成员 - Lambda 语法

python - 使用稀疏张量为 TensorFlow 中的 softmax 层提供占位符

python - 无法使用 pip 安装 lxml