简而言之,我需要根据索引从列表中删除多个项。但是,我不能使用pop,因为它会移动索引(没有一些笨拙的补偿系统)。有办法同时删除多个项目吗?
我有一个遍历列表的算法,如果条件正确,则通过pop方法删除该项。当这一切都在一个循环中完成时,就会出现一个问题。pop完成后,列表将缩短一个,将所有值替换为一个。所以循环会超出范围。是否可以同时删除多个项目,或另一个解决方案?
我的问题的一个例子:
L = ['a', 'b', 'c', 'd']
for i in range(len(L)):
print L
if L[i] == 'a' or L[i] == 'c':
L.pop(i)
你的单子大吗?如果是的话,使用^{} 中的
ifilter
来过滤掉那些您不需要的元素(无需预先支付费用)。单子不那么大?使用列表理解:
这将创建列表的新副本。这通常不是一个效率问题,除非你真的关心内存消耗。
作为语法方便性和惰性的一个好媒介(=大列表的效率),您可以使用
(
)
而不是[
]
来构造生成器而不是列表:在此之后,您可以在
interestingelts
上迭代,但不能索引到它:你想要一个列表理解:
或者,如果您真的不想创建副本,请返回:
感谢ncoghlan的建议。(我决定将其保留为
L.pop(i)
,因为问题最初是这样表述的。)而且,正如J.S.Sebastian正确指出的那样,向后走是有空间效率的,但时间效率低;大多数情况下,列表理解或生成器(
L = (...)
而不是L = [...]
)是最好的。编辑:
好吧,既然人们似乎想要比上述相反的方法慢得多的东西(我无法想象为什么。。。:)这里有一个顺序保持的就地过滤器,它的速度应该与列表理解的速度只有常数不同。(这类似于我在c中过滤字符串时所做的操作。)
小结
str.translate()
删除字符del L[i]
很慢如果项是与示例中相同的字节,则可以使用^{} :
通常,可以使用切片删除多个项目:
正如前面提到的@phooji和@senderle那样,列表理解(或生成器表达式)在您的情况下更可取:
下面是
L=list("abcd"*10**5); delitems="ac"
的性能比较:其中
由于使用} 速度较慢。每一个
O(N**2)
算法,^{del L[i]
都可能导致右边的所有项向左移动以缩小间隙。上表中的“时间”列包括创建新输入列表(第一行)所需的时间,这是由于某些算法会修改输入位置。
以下是相同输入但不在每次迭代中创建新列表的计时:
该表显示^{} 与listcomp相比没有显著改进。
一般来说,考虑此类任务的性能是不值得的,甚至是有害的,除非探查器证明此代码是一个瓶颈,并且对您的程序非常重要。但是了解能够在速度上提供超过一个数量级改进的替代方法可能是有用的。
相关问题 更多 >
编程相关推荐