在迭代列表时添加元素是否正确?

6
我看到我可以在迭代列表时添加元素。
lst = [1]
for i in lst:
    lst.append(i+1)
    print(i)

我可以使用这种行为吗?还是不被鼓励?我注意到对于set来说并非如此。
lst = set([1])
for i in lst:
    lst.add(i+1)
    print(i)

错误:迭代过程中大小发生变化。

3
不被禁止,但第一个循环将永远运行。 - timgeb
1
@timgeb 我明白这个循环会一直运行下去。这只是为了演示目的。 - Rahul Gopinath
3个回答

6
在迭代列表时添加元素是允许的,因为列表是有序的,因此在迭代期间进行添加操作的行为是可以预测的。这使得在所有其他队列任务完成后重试失败的任务变得非常有用,例如:
tasks = ['task1', 'task2']
for task in tasks:
    if task == 'task1':
        tasks.append('task1-retry')
    print(task)

这将输出:
task1
task2
task1-retry

但是集合无序,所以在按顺序迭代集合时向集合添加项目具有不确定的效果,因此被禁止。


3
如果我尝试以类似的方式更新字典,我会得到相同的错误(“字典大小已更改”)。由于Python3中的字典是有序的,因此这种推理是否也适用于字典? - Rahul Gopinath
@rahul Python 3.7+保证字典记住插入顺序。(但是仍然会抛出RuntimeError异常。) - timgeb

1

就像其他人已经说过的那样,你会创建一个无限循环。但是在Python中可以使用break语句来捕获它: https://docs.python.org/2.0/ref/break.html

不过,如果你用break语句捕获它,你可以将其重写为另一个循环,在这个循环中,只要满足你用于break语句的条件,它就会停止。


0

我认为这样做不会起作用,因为如果列表大小改变,那么循环项也应该随之改变,否则可能会变成无限循环或者内存访问冲突。最好这样做:

list=[1,2,7,5]
list2=[]
for i in list:
  list2.append(i+1)
  print(i)
list=list+list2

列表推导式有什么问题吗?list1 += [i+1 for i in list1] - bruno desthuilliers
顺便说一下,如果不在手动杀死之前,OP的第一个片段确实会进入无限循环并最终耗尽所有内存。 - bruno desthuilliers

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