项目中的x与xml.etree.ElementTree.Element.remove的列表(项目)之间的差异

时间:2014-09-22 22:03:18

标签: python xml.etree

下面我有一个简单的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,我可以清楚地看到相同的元素以两种方式打印。那究竟发生了什么?

1 个答案:

答案 0 :(得分:1)

迭代时不得修改集合。 Python 2.7 doc没有清楚地解释它,但这里是Python 3 doc says

  

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