如果我想迭代添加的值,在迭代期间附加到列表是否安全?

Joe*_*oel 6 python loops

我经常发现自己编写的代码如下:

mylist = [247]
while mylist:
    nextlist = []
    for element in mylist:
        print element
        if element%2==0:
            nextlist.append(element/2)
        elif element !=1:
            nextlist.append(3*element+1)
    mylist = nextlist
Run Code Online (Sandbox Code Playgroud)

好的 - 它通常不是这么简单[通常它确实是长列表,我只是选择了这个(参见xkcd)的乐趣],但我创建了一个列表,迭代它用这些元素做事情.在这样做的过程中,我将发现需要迭代的新事物,然后将它们放入一个新的列表中,然后迭代.

似乎可以写:

mylist=[247]
for element in mylist:
    print element
    if element%2 == 0:
        mylist.append(element/2)
    elif element !=1:
        mylist.append(element*3+1)
Run Code Online (Sandbox Code Playgroud)

我知道在迭代时修改列表被认为是危险的,但在这种情况下我想迭代新元素.

这样做会有危险吗?我唯一能想到的是列表可能会增长并占用大量内存(在我的许多情况下,我实际上希望最终得到整个列表).还有其他我无视的吗?

请注意:Python:迭代时将元素添加到列表是相关的,但是解释了创建列表副本的方法,以便我们可以避免迭代原始列表.我问的是我的具体情况是否有任何错误,我实际上希望扩展我的迭代.


编辑:这里更接近真正的问题.假设我们想要生成网络的"k-core".也就是说,删除程度小于k的所有节点.从剩余网络中删除程度小于k的所有节点.重复,直到没有人删除.该算法将首先找到少于k个节点,将它们放在to_delete列表中.然后,当删除节点时,如果邻居的度数变为k-1,则将其添加到列表中.这可以通过以下方式完成:

delete_list = [node for node in G.nodes() if G.degree(node)<k]
for node in delete_list:
    nbrs = G.neighbors(node)
    for nbr in nbrs:
        if G.degree(nbr)==k:
            delete_list.append(nbr)
    G.remove_node(node)
Run Code Online (Sandbox Code Playgroud)

Cyp*_*ase 5

是的,附加到你正在迭代的列表是相当安全的,至少在你正在做的方式.唯一的问题是,如果列表变得如此之大,以至于它会导致内存问题,尽管这对于数量非常大的问题只会是一个问题.

也就是说,while在这种情况下我可能会使用一个循环,无论你是否想要在最后都有整个列表.

current = 247
result_list = [current]

while current != 1:
    if current % 2 == 0:
        current /= 2
    else:
        current = current * 3 + 1

    result_list.append(current)
Run Code Online (Sandbox Code Playgroud)

虽然我真的可能会使用发电机.

def collatz(start):
    current = start

    yield current

    while current != 1:
        if current % 2 == 0:
            current /= 2
        else:
            current = current * 3 + 1

        yield current
Run Code Online (Sandbox Code Playgroud)

Collat​​z猜想大喊大叫!:d