代码优化:while或for(或其他)?

2024-09-30 01:23:33 发布

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

我有这样一个列表(为了简单起见,我使用整数累进数,但它们实际上是浮动汇率):

List = [4,5,6,7,8,9,10,11,12]     #__len__ = 9

我需要“延迟”(偏移)这个列表off=3(但是这个数字3可能是可变的),方法是为第一个“off”值加上“0”,然后从“off+1”开始,值在列表的“0”位置:

OffsetList = [0,0,0,4,5,6,7,8,9]   #__len__ = 9

我已经考虑过这两种可能的解决方案,但我对编程非常陌生,我想从某人那里得到一个意见,即什么是最优化的解决方案,以及是否有可能开发出一种不同的解决方案,它可能比我想的更好:

#SOLUTION 1
OffsetList = []
for _ in range(0,off):
    OffsetList.append(0)
for k in range(0, len(List) - off):
    OffsetList.append(List[k])

#SOLUTION 2
OffsetList = []
for _ in range(0,off):
    OffsetList.append(0)
j = 0
while len(OffsetList) < len(List):
    OffsetList.append(List[j])
    j += 1

你认为哪一个更优化(快速、安全、稳定等),为什么?另外(我肯定),有没有比我想的两个更好的解决方案?你知道吗


Tags: 方法in列表forlenrange数字整数
3条回答

最好不要在添加0时显式地遍历列表

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

Sidenote:我正在使用iPython%timeit魔术,它使用Python的内置timeitmodule。您也可以直接调用time-it模块python -m timeit --setup 'n=50;l=[1,2,3,4,5]' 'l = [0] * n + l',但是使用iPython会让事情变得更简单。你知道吗

一般来说,Python中的显式循环比列表理解慢,但这并不适用于所有内容,也不意味着您应该尝试将所有内容作为列表理解编写。见this article。我不明白为什么要使用while循环,当你清楚你想要什么时,在列表的开头添加n元素。在这种情况下,我更喜欢这样的代码:l = [0] * offset + l它的意图非常清楚。你知道吗

来自JoelCornett的评论

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

注意prefix5是以纳秒为单位测量的,其他的是微秒。你知道吗

prefix3prefix4 & prefix5之间的区别在于itertools.chain返回一个迭代器(没有随机访问,不能对其调用len)。因此,将其放入prefix3中的一个列表需要开销。如果您只对迭代元素感兴趣,而不是通过索引访问特定的元素,那么应该使用prefix5,否则使用prefix2prefix3。你知道吗

可以使用列表切片:

>>> List = [4,5,6,7,8,9,10,11,12]
>>> off = 3
>>> OffsetList = [0]*len(List)
>>> OffsetList[off:] = List[:-off]
>>> OffsetList
[0, 0, 0, 4, 5, 6, 7, 8, 9]

您可以使用列表理解:

List = [4,5,6,7,8,9,10,11,12]
off = 3
OffsetList = [0 for x in xrange(off)] + List[:-off]
print OffsetList

相关问题 更多 >

    热门问题