出于好奇:哪一个更适合创造一个总和?总和(列表)与累加

2024-06-17 08:22:25 发布

您现在位置:Python中文网/ 问答频道 /正文

我在计算一条路线的总距离(对于一个旅行推销员的问题),我很好奇哪个更好:对一系列整数求和,或者使用total+=value(不知道这个术语是什么)。。我相信是连锁的。换句话说:

totalDistance = [distance(location, location+1) for location in route]
return sum(totalDistance)

或者

totalDistance = 0
for location in route:
    totalDistance += distance(location, location+1)
return totalDistance

distance()返回一个int值,不同路由的位置数在0到100之间变化。 对任何一种方法(或完全不同的方式)的想法表示感谢!你知道吗

编辑:

积累,而不是串联。你知道吗


Tags: in距离forreturnvaluelocation整数路线
3条回答

最好的方法是只使用带有sum的生成器表达式

return sum(distance(location, location+1) for location in route)

这节省了创建列表的开销。 totalDistance=[距离(位置,位置+1)表示路线中的位置]

for循环版本也不会创建列表。很好,只是和使用sum相比有点冗长。sum正是在这种情况下存在的

location+1是如何工作的?好像是route的下一个项目


出于兴趣,我比较了pypy2.2.1中的@iCodez示例。每个函数的第一次运行是允许JIT编译函数

>>>> from timeit import timeit
>>>> def f():
....     number = 0
....     for i in range(100):
....         number += 1
.... 
>>>> timeit(f)
0.3245859146118164
>>>> timeit(f)
0.2913198471069336

>>>> def g():
....     lst = [i for i in range(100)]
....     sum(lst)
.... 
>>>> timeit(g)
0.8840188980102539
>>>> timeit(g)
0.8698201179504395

>>>> def h():
....     sum(i for i in range(100))
.... 
>>>> timeit(h)
2.8281970024108887
>>>> timeit(h)
2.8702847957611084

哇..genexp的性能差多了

在我的机器上,遍历生成器比遍历列表慢:

from timeit import timeit

# just for simulation
def distance(la, lb):
    return abs(la-lb)

# for simulation, too    
def route():
    return xrange(10000)

# the longer(code) and faster but wasteful(memory) way
def longer_faster_wasteful():
    return sum([distance(location, location+1) for location in route()])

# the shorter(code) and saving(memory) but slower way
def shorter_slower_saving():
    return sum(distance(location, location+1) for location in route())

# print 2.01163072818 on my machine
print timeit(longer_faster_wasteful, number=100)

# print 2.91834802689 on my machine
print timeit(shorter_slower_saving, number=100)

为什么不将generator expressionsum一起使用:

return sum(distance(location, location+1) for location in route)

这个解决方案避免了像第一个解决方案那样创建一个不必要的列表(节省内存消耗),而且比第二个解决方案简洁得多(清洁度很重要)。你知道吗

也就是说,您总是可以将第一个解决方案合并为一个线性:

return sum([distance(location, location+1) for location in route])

但是,就像我上面说的,为什么要创建一个列表来丢弃它呢?你知道吗

相关问题 更多 >