img {
display: block;
border-radius: 100px;
border: 1px solid #fff;
width: 80px;
height: 80px;
margin: 30px auto 0;
box-shadow: 0px 0px 4px rgba(0,0,0,0.7);
margin-top: 0px;
}
和sum(list)
之间有什么区别
reduce(lambda total , element : total + element, list)
答案 0 :(得分:3)
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 needs more parentheses')
。
我认为这有点极端,我知道我不是唯一一个在Python中发现reduce
很好用的人(其他核心开发人员不会说服Guido这么做)将其移至functools
而不是在3.0中将其删除…),但是它确实会引发一个标志,使我可以更加仔细地查看我的代码(或其他人的代码),以查看是否存在更Python化的编写方式,而且经常有。
reduce
可以做除求和以外的其他事情。例如,假设您要用一堆数字创建一个数字:
def fromdigits(*digits, base):
return reduce(lambda acc, digit: base*acc + digit), digits, 0)
尝试用sum
来写。
(尽管我敢打赌,这个例子只是让Guido哭了,但这是我想到的第一件事不是关于树木的……)
答案 1 :(得分:1)
从逻辑上讲,sum(list)
和reduce(lambda total, element: total + element, list, 0)
之间没有区别(请注意,默认值作为第三个参数传递给reduce
)。
sum
有一些细微差别;它有一个特殊的快速路径来求和较小的整数(当总和可以放入C long
时),它避免了每次添加Python级别的函数调用,并且即使求和str
对象也是如此给定start
的值''
(从逻辑上没有阻止它,但是在str
上使用重复加法效率极低,因此它拒绝str
将用户指向{{1 }},这是连接许多''.join
的正确方法。
与str
不同,sum
可以与任何可加类型一起使用,只要输入中至少包含一个元素(其中reduce
要求您传递一个{{1 }}值(用于任何非数字类型)。
通常,您应为此目的使用sum
(或将start
使用sum
或将{{1} 1}} / ''.join
); str
的专业性较弱,速度较慢,维护人员通常认为较难理解。