<p>最好不要在添加0时显式地遍历列表</p>
<pre><code>def prefix1(l, offset):
return l = [0] * offset + l
def prefix2(l, offset):
for _ in xrange(offset):
l.insert(0, 0)
return l
>>> %timeit prefix1([1,2,3,4,5], 500)
10000 loops, best of 3: 4.87 µs per loop
>>> %timeit prefix2([1,2,3,4,5], 500)
10000 loops, best of 3: 190 µs per loop
</code></pre>
<p><em>Sidenote</em>:我正在使用iPython<code>%timeit</code>魔术,它使用Python的内置<code>timeit</code><a href="http://docs.python.org/2/library/timeit.html" rel="nofollow">module</a>。您也可以直接调用time-it模块<code>python -m timeit --setup 'n=50;l=[1,2,3,4,5]' 'l = [0] * n + l'</code>,但是使用iPython会让事情变得更简单。你知道吗</p>
<p>一般来说,Python中的显式循环比列表理解慢,但这并不适用于所有内容,也不意味着您应该尝试将所有内容作为列表理解编写。见<a href="http://blog.cdleary.com/2010/04/efficiency-of-list-comprehensions/" rel="nofollow">this article</a>。我不明白为什么要使用while循环,当你清楚你想要什么时,在列表的开头添加<code>n</code>元素。在这种情况下,我更喜欢这样的代码:<code>l = [0] * offset + l</code>它的意图非常清楚。你知道吗</p>
<p>来自<code>JoelCornett</code>的评论</p>
<pre><code>import itertools
def prefix3(l, offset):
return list(itertools.chain([0] * offset, l))
def prefix4(l, offset):
return itertools.chain([0] * offset, l)
def prefix5(l, offset):
return itertools.chain(itertools.repeat(0, offset), l)
>>> %timeit prefix3([1,2,3,4,5], 500)
10000 loops, best of 3: 13 µs per loop
>>> %timeit prefix4([1,2,3,4,5], 500)
10000 loops, best of 3: 2.9 µs per loop
>>> %timeit prefix5([1,2,3,4,5], 500)
10000 loops, best of 3: 883 ns per loop
</code></pre>
<p>注意<code>prefix5</code>是以纳秒为单位测量的,其他的是微秒。你知道吗</p>
<p><code>prefix3</code>和<code>prefix4 & prefix5</code>之间的区别在于<code>itertools.chain</code>返回一个迭代器(没有随机访问,不能对其调用<code>len</code>)。因此,将其放入<code>prefix3</code>中的一个列表需要开销。如果您只对迭代元素感兴趣,而不是通过索引访问特定的元素,那么应该使用<code>prefix5</code>,否则使用<code>prefix2</code>或<code>prefix3</code>。你知道吗</p>