在迭代时向列表添加元素

13
我需要这种行为,但是我宁愿有一个递减的列表而不是一个递增的列表。序列顺序对于此操作很重要。
for item in mylist:
    if is_item_mature(item):
        ## Process him
    else:
        ## Check again later
        mylist.append(item)

但我更希望它像这样。它的行为是否符合我的想法?有更好的方法吗?

while mylist:
    item = list.pop(0)
    if is_item_mature(item):
        ##Process
    else:
        mylist.append(item)

是的,它看起来表现得像你想象中的那样。但它是否按照你预期的方式工作呢? - Wild Pete
1
“list” 不是一个好的变量名称选择。 - Benjamin Hodgson
一切似乎都很好,唯一的问题是在最后几个项目上出现了死锁(我的数据集的一部分存在错误)。调试器捕获了队列追逐自己尾巴的情况。 - user2097818
2个回答

11
你的方法唯一的问题在于,随着使用次数的增加,列表会越来越长,可能会占用大量内存。
我建议你使用队列。队列的设计足够灵活,可以处理双端生产和消费。
from Queue import Queue
q = Queue() #You can also specify the maximum size of the Queue here
# Assume your Queue was filled
while not q.empty():
    # It won;t block if there are no items to pop
    item = q.get(block = False) 
    if is_item_mature(item):
        #process
    else:
        #In case your Queue has a maxsize, consider making it non blocking
        q.put(item) 

我认为我也喜欢这个。目前我的循环处理有些粗糙,严格的顺序可以暂时省去一些额外的代码。 - user2097818
Queue.Queue 用于多线程。如果您不需要它,只需使用 collections.deque,它在 Queue 内部使用。 - koddo

9

您可以安全地向列表中添加项目,迭代将包括这些项目:

>>> lst = range(5)
>>> for i in lst:
...     print i
...     if i < 3:
...         lst.append(i + 10)
... 
0
1
2
3
4
10
11
12

然而,如果你更喜欢一个逐渐减少的列表,那么你的while循环完全适合你的需求。


1
你如何知道这是安全的,并且能按照那样工作?有没有文件记载这个?我已经尝试过很长时间来寻找一些证据…… - Stefan Pochmann
1
@StefanPochmann:我怎么知道?通过对列表和列表迭代器实现细节的经验和了解。这并没有明确记录。 - Martijn Pieters
1
@StefanPochmann:由iter(list)返回的列表迭代器存储当前位置(整数)和对列表的引用。每次获取下一个元素时,都会将当前位置与当前列表大小进行比较,如果它小于当前列表大小,则从列表中检索当前位置处的项,增加位置,然后返回检索到的项。 - Martijn Pieters
1
@StefanPochmann:这使得扩展或缩小列表变得安全;每次都会测试长度。无论列表在中间发生了什么,位置都会增加,这就是为什么在当前位置之前或之前删除元素通常是一个坏主意(内容会移动,但当前位置不会相应地调整)。 - Martijn Pieters
1
那么他们也可以将其记录下来以使其正式化,这样我就能睡得更好了 :-)。是的,我以前用过iter+next来跳过,但那需要更多的代码,而我想让它更简短。 (顺便说一句,您有一个错别字,item(seq) -> iter(seq)) - Stefan Pochmann
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接