首先,我通过纯粹的好奇心来问这个问题,看看一些伟大的单线技能。 sum()
函数仍然是对列表中的对象求和的最佳函数。
但正如所说的那样,我纯粹的好奇心问:有没有办法在一行中对list
(很明显,不使用sum()
)中的对象进行求和?假设列表为range(0, 100)
我完全不知道如何实现这一目标,但由于Python非常灵活,所以我毫不怀疑它是可能的。
答案 0 :(得分:6)
您可以使用reduce
和附加功能(例如lamdba
expression或operator.add
)采取功能性方法:
>>> from operator import add
>>> reduce(add, range(0, 100))
4950
(请注意,在3.x中,您需要先from functools import reduce
。)
根据文档,reduce(function, iterable)
将
将
function
两个参数累加到iterable
的项目,从左到右,以便将iterable
缩减为单个值。
答案 1 :(得分:2)
只是为了好玩,这是一个根本不需要内置功能的解决方案。它基本上是reduce
的重新实现,使用了一些lambda魔法。
>>>>(lambda f: lambda *args: f(f, *args))(lambda self, f, seq, d: d if not seq else f(seq[0], self(self, f, seq[1:], d)))(lambda a,b: a+b, range(100), 0)
4950
答案 2 :(得分:1)
Python可能不是递归方法的最佳语言,因为(1)它不支持尾递归(2)函数调用非常昂贵(3)递归限制可防止深度递归和(4)切片序列使用O(n)
进行缩放(其中n
是切片中元素的数量)。
但是你可以将它们用于单行!
一种方法就是成功弹出并添加第一个元素直到序列耗尽:
>>> sum_func = lambda x: x[0] + sum_func(x[1:]) if x else 0
>>> sum_func(range(100))
4950
只要if x
(that is to say x
is not empty),第一部分就会被触发。这种方法显示了在Python中使用recusion的所有缺点:它达到了长度约为300的序列的递归限制,它与O(n**2)
成比例,并且与内置{{1}相比它真的很慢}和sum
接近。
通过使用分而治之的递归方法,可以减轻其中一个缺点:
reduce
这一次它会对列表的两半进行递归,从而将回归深度从>>> sum_func = lambda x: sum_func(x[:len(x)//2]) + sum_func(x[len(x)//2:]) if len(x) > 1 else x[0]
>>> sum_func(range(100))
4950
减少到n
,因此它可以处理更长的序列。然而,它并不比上面那个快。
当然,总是有作弊选择:
log2(n)
如果你真的想要它真的很快: - )