以下是我使用Python编写的一些代码:
from math import sqrt
abundant_list = []
for i in range(12,28123+1):
dividor_list = [1]
for j in range(2, int(sqrt(i))+1):
if i%j == 0:
dividor_list.extend([i/j,j])
if sum(dividor_list) > i:
abundant_list.append(i)
print abundant_list
正如您所看到的,代码实际上是尽可能地提高效率。
如果我使用list.append
两次,或list.extend
只使用一次,会有什么不同吗?
我知道这可能是微小的差异,但我真的想知道:)
答案 0 :(得分:18)
import timeit
def append2x(foo):
foo.append(1)
foo.append(1)
def extend_lst(foo):
foo.extend([1,1])
def extend_tup(foo):
foo.extend((1,1))
l1 = []
l2 = []
l3 = []
print timeit.timeit('append2x(l1)',setup = 'from __main__ import append2x,l1')
print timeit.timeit('extend_lst(l2)',setup = 'from __main__ import extend_lst,l2')
print timeit.timeit('extend_tup(l3)',setup = 'from __main__ import extend_tup,l3')
这是一个简单的基准。我的结果(os-X,10.5.8,core2duo,FWIW):
0.520906925201 #append
0.602569103241 #extend-list
0.357008934021 #extend-tuple
和我的linux盒子(Ubuntu,x86-64核心i7)的结果排序相同:
0.307395935059 #append
0.319436073303 #extend-list
0.238317012787 #extend-tuple
对我而言,这表示extend
比append
更快,但与创建list
tuple
的费用相对较高
在下面的评论中指出,由于元组的不变性,解释器可以优化元组的创建(它创建元组一次并重复使用它)。如果我们将代码更改为:
def extend_lst(foo):
v = 1
foo.extend([v,v])
def extend_tup(foo):
v = 1
foo.extend((v,v))
时间几乎相同:
0.297003984451 #append
0.344678163528 #extend-list
0.292304992676 #extend-tuple
虽然tuple
仍然始终胜过列表版本,但我所做的所有试验几乎都没有append
版本。
我从这里得到的一件事是,如果你在一个包含所有文字的对象上进行迭代,那么选择一个tuple
而不是list
。如果它不完全由文字组成,那么选择list
还是tuple
无关紧要。
答案 1 :(得分:10)
值得指出的是,这个问题的答案取决于每次迭代时添加的列表/元组的小尺寸。对于较大的列表,扩展显然是优越的(列表与元组没有区别)。从mgilson' answer开始,我检查了包含600个项目的集合的行为,而不是2:
调用追加600次所需的时间是使用extend()
和手动定义的列表/元组(即[v,v,v,v,v,v,v...]
)的8倍:
42.4969689846
5.45146393776
5.38034892082
这五秒钟中的大部分实际上是列表/元组创建。在timeit
调用之前准备它会将时间延长到
1.42491698265
0.657584905624
分别为list和tuple。
对于更现实(更公平)的情况,可以在函数调用中动态生成数据:
import timeit
def append_loop(foo, reps):
for i in range(reps):
foo.append(i)
def append_comp(foo, reps):
[foo.append(i) for i in range(reps)]
def extend_lst(foo, reps):
foo.extend([i for i in range(reps)])
def extend_tup(foo, reps):
foo.extend((i for i in range(reps)))
repetitions = 600
print timeit.timeit('append_loop([], repetitions)', setup='from __main__ import append_loop, repetitions')
print timeit.timeit('append_comp([], repetitions)', setup='from __main__ import append_comp, repetitions')
print timeit.timeit('extend_lst([], repetitions)', setup='from __main__ import extend_lst, repetitions')
print timeit.timeit('extend_tup([], repetitions)', setup='from __main__ import extend_tup, repetitions')
(追加是通过for-loop和list comprehension实现的,以分解两种循环方式之间的效率差异。)
时间是:
53.8211231232
57.1711571217
19.8829259872
28.5986201763
正如我们所看到的,扩展列表理解仍然比追加快两倍。此外,元组理解似乎明显慢于列表理解,append_comp
仅引入不必要的列表创建开销。
答案 2 :(得分:0)
他们完全相同。
以下是您的代码所用的时间:
使用dividor_list.extend([i/j,j])
>>>
0:00:00.410000
>>>
0:00:00.383000
>>>
0:00:00.389000
使用dividor_list.append(i/j); dividor_list.append(j)
>>>
0:00:00.400000
>>>
0:00:00.390000
>>>
0:00:00.381000