首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何通过就地过滤修改python集合?

如何通过就地过滤修改python集合?
EN

Stack Overflow用户
提问于 2011-11-07 13:59:37
回答 7查看 11.8K关注 0票数 15

我想知道,Python中是否存在修改集合而不创建新集合的方法。例如:

代码语言:javascript
运行
复制
lst = [1, 2, 3, 4, 5, 6]
new_lst = [i for i in lst if i > 3]

工作正常,但是创建了一个新的集合。是不是因为Python缺少一个filter()方法(或类似的方法)来修改集合对象呢?

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2011-11-07 14:05:50

其他答案是正确的;如果希望指向旧列表的所有名称指向新列表,则可以使用片赋值。

然而,这并不是真正的就地创建;新列表首先是在其他地方创建的。斯文回答中的联系很好。

没有一个真正的就地操作的原因是,当创建一个像O(n)这样的新列表时,每个真正的就地项删除都是O(k)本身,其中k是从删除点开始的列表的长度。使用Python列表避免这种情况的唯一方法是使用一些临时存储,这就是通过使用片分配所要做的事情。

collections.deque上的就地O(n)过滤器示例,以防您不需要将数据存储在list中。

代码语言:javascript
运行
复制
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])
票数 12
EN

Stack Overflow用户

发布于 2011-11-07 14:01:33

如果你想就地取材,只需使用

代码语言:javascript
运行
复制
lst[:] = [i for i in lst if i > 3]

这个won't be faster or save any memory,但它改变了对象的位置,如果这是您需要的语义。

票数 29
EN

Stack Overflow用户

发布于 2011-11-07 14:21:15

纠正@larsmans original solution,你可以

代码语言:javascript
运行
复制
    i = 0
    while i < len(lst):
        if lst[i] <= 3:
            del lst[i]
        else:
            i += 1

代码语言:javascript
运行
复制
    i = len(lst)
    while i > 0:
        if lst[i-1] <= 3:
            del lst[i-1]
        i -= 1

原因是del发生了“指数转移”。如果我在某个索引处执行del,则需要重新检查该索引,因为它现在拥有一个不同的值。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/8037455

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档