我经常发现自己编写的代码如下:
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)
是的,附加到你正在迭代的列表是相当安全的,至少在你正在做的方式.唯一的问题是,如果列表变得如此之大,以至于它会导致内存问题,尽管这对于数量非常大的问题只会是一个问题.
也就是说,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)
向Collatz猜想大喊大叫!:d