我想知道,Python中是否存在修改集合而不创建新集合的方法。例如:
lst = [1, 2, 3, 4, 5, 6]
new_lst = [i for i in lst if i > 3]
工作正常,但是创建了一个新的集合。是不是因为Python缺少一个filter()
方法(或类似的方法)来修改集合对象呢?
发布于 2011-11-07 14:05:50
其他答案是正确的;如果希望指向旧列表的所有名称指向新列表,则可以使用片赋值。
然而,这并不是真正的就地创建;新列表首先是在其他地方创建的。斯文回答中的联系很好。
没有一个真正的就地操作的原因是,当创建一个像O(n)这样的新列表时,每个真正的就地项删除都是O(k)本身,其中k
是从删除点开始的列表的长度。使用Python列表避免这种情况的唯一方法是使用一些临时存储,这就是通过使用片分配所要做的事情。
collections.deque
上的就地O(n)过滤器示例,以防您不需要将数据存储在list
中。
from collections import deque
def dequefilter(deck, condition):
for _ in xrange(len(deck)):
item = deck.popleft()
if condition(item):
deck.append(item)
deck = deque((1, 2, 3, 4, 5))
dequefilter(deck, lambda x: x > 2) # or operator.gt(2)
print deck
# deque([3, 4, 5])
发布于 2011-11-07 14:01:33
如果你想就地取材,只需使用
lst[:] = [i for i in lst if i > 3]
这个won't be faster or save any memory,但它改变了对象的位置,如果这是您需要的语义。
发布于 2011-11-07 14:21:15
纠正@larsmans original solution,你可以
i = 0
while i < len(lst):
if lst[i] <= 3:
del lst[i]
else:
i += 1
或
i = len(lst)
while i > 0:
if lst[i-1] <= 3:
del lst[i-1]
i -= 1
原因是del
发生了“指数转移”。如果我在某个索引处执行del
,则需要重新检查该索引,因为它现在拥有一个不同的值。
https://stackoverflow.com/questions/8037455
复制相似问题