xml.etree.ElementTree.Element.remove的项和列表中的x之间的差异



下面我有一个简单的XML结构

<T1>
    <T2>
        <override select="A,B,C">
            <B>Hello</B>
        </override>
        <override select="A">
            <A>Hello</A>
        </override>
    </T2>
</T1>

在这个例子中,我试图删除任何属于override的标签
假设我有以下设置代码:

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文档所说的:

注意当循环修改序列时会有一个微妙之处(这只能发生在可变序列,即列表)。内部计数器用于跟踪下一个要使用的项,并且在每次迭代时都会递增。当这个计数器达到序列的长度时,循环终止。这意味着,如果套件从序列中删除当前(或上一个)项目,则将跳过下一个项目(因为它获得了已处理的当前项目的索引)。同样,如果套件在当前项之前的序列中插入一个项,则下次通过循环时将再次处理当前项。这可能会导致严重的错误,可以通过使用整个序列的切片进行临时复制来避免

最新更新