我有一个奇怪的问题.有人看到我的代码有什么问题吗?
for x in questions:
forms.append((SectionForm(request.POST, prefix=str(x.id)),x))
print "Appended " + str(x)
for (form, question) in forms:
print "Testing " + str(question)
if form.is_valid():
forms.remove((form,question))
print "Deleted " + str(question)
a = form.save(commit=False)
a.audit = audit
a.save()
else:
flag_error = True
Run Code Online (Sandbox Code Playgroud)
结果是:
Appended Question 50
Appended Question 51
Appended Question 52
Testing Question 50
Deleted Question 50
Testing Question 52
Deleted Question 52
Run Code Online (Sandbox Code Playgroud)
它似乎跳过问题51.它被附加到列表中,但for循环跳过它.有任何想法吗?
Jus*_*ier 12
您正在修改forms正在迭代的对象的内容,当您说:
forms.remove((form,question))
Run Code Online (Sandbox Code Playgroud)
根据声明的Python文档for,这不安全(重点是我的):
Python中的for语句与您在C或Pascal中使用的语句略有不同.而不是总是迭代数字的算术级数(如在Pascal中),或者让用户能够定义迭代步骤和暂停条件(如C),Python的for语句迭代任何序列的项目(列表或字符串),按照它们出现在序列中的顺序.
修改循环中迭代的序列是不安全的(这只能发生在可变序列类型中,例如列表).如果您需要修改正在迭代的列表(例如,复制所选项目),则必须迭代副本.切片表示法使这特别方便:
Run Code Online (Sandbox Code Playgroud)for x in a[:]: # make a slice copy of the entire list ... if len(x) > 6: a.insert(0, x)
另请参阅Python语言参考中的这一段,它准确地解释了发生了什么:
当循环修饰序列时有一个微妙的变化(这只能发生在可变序列,即列表中).内部计数器用于跟踪下一个使用的项目,并在每次迭代时递增.当该计数器达到序列的长度时,循环终止.这意味着如果套件从序列中删除当前(或前一个)项目,则将跳过下一个项目(因为它获取已经处理的当前项目的索引).同样,如果套件在当前项目之前的序列中插入项目,则下次循环时将再次处理当前项目.
有很多解决方案.您可以按照他们的建议制作副本.另一种可能性是由于第二次for循环而创建一个新列表,而不是forms直接修改.这个选择由你...
| 归档时间: |
|
| 查看次数: |
1638 次 |
| 最近记录: |