差异在xml.etree.ElementTree.Element.remove
问题描述:
项目和列表(项目)下面我有差异在xml.etree.ElementTree.Element.remove
<T1>
<T2>
<override select="A,B,C">
<B>Hello</B>
</override>
<override select="A">
<A>Hello</A>
</override>
</T2>
</T1>
在这个例子中,我试图删除任何标记,是override
一个简单的XML结构。
假设我有设置以下代码:
import xml.etree.ElmenentTree as ET
tree = ET.parse(file)
root = tree.getroot()
如果我下面的一个因素依然存在:
for parent in root.iter():
for child in parent:
if child.tag == 'override':
parent.remove(child)
但是,如果我指定list(parent)
,而不是仅仅in parent
,那么它的工作原理:
for parent in root.iter():
for child in list(parent):
if child.tag == 'override':
parent.remove(child)
这是为什么发生?如果在删除之前打印出child
,我可以清楚地看到相同的元素以两种方式打印。那么究竟发生了什么?
答
您在迭代时不得修改集合。 Python 2.7版文档不解释清楚,但这里是Python 3 doc says:
注意有序时,由循环修改(这只能发生于可变序列,即列表)一个微妙。内部计数器用于跟踪下一个使用的项目,并在每次迭代时递增。当该计数器达到序列长度时,循环终止。这意味着如果套件从序列中删除当前(或前一个)项目,则下一个项目将被跳过(因为它获取了已处理的当前项目的索引)。同样,如果套件在当前项目之前插入序列中的项目,则当前项目将在下一次循环中再次处理。这可能会导致可以通过使用整个序列片段临时复制来避免的令人讨厌的错误
您正在迭代可变集合并在迭代过程中对其进行更改。这是一个禁忌。请参阅['for'语句](https://docs.python.org/2/tutorial/controlflow.html#for-statements) – roippi 2014-09-22 22:07:46