在python中使用for循环时重置变量

在python中使用for循环时重置变量,python,xml,python-3.x,elementtree,Python,Xml,Python 3.x,Elementtree,我是一个相对较新的程序员,使用xml元素树来迭代成员数据的xml文件。我正在遍历成员以提取数据并分配给姓氏、名字和id的变量 我遇到的问题是,如果其中一个成员缺少一个元素(而不是元素中缺少数据),那么我当前的代码将维护上一次迭代(member)中的变量值 我的数据: <?xml version='1.0' ?> <members> <member> <field name="surname"> <

我是一个相对较新的程序员,使用xml元素树来迭代成员数据的xml文件。我正在遍历成员以提取数据并分配给姓氏、名字和id的变量

我遇到的问题是,如果其中一个成员缺少一个元素(而不是元素中缺少数据),那么我当前的代码将维护上一次迭代(member)中的变量值

我的数据:

<?xml version='1.0' ?>
<members>
    <member>
        <field name="surname">
            <text>Smith</text>
        </field>
        <field name="firstname" type="text">
            <text>John</text>
        </field>
        <field name="id" type="text">
            <text>123</text>
        </field>
    </member>
        <member>
        <field name="surname" type="text">
            <text>Bloggs</text>
        </field>

<!--missing firstname element here -->

        <field name="id" type="text">
            <text>789</text>
        </field>
    </member>
    <member>
        <field name="surname" type="text">
            <text>Jones</text>
        </field>
        <field name="firstname" type="text">
            <text>Jane</text>
        </field>
        <field name="id" type="text">
            <text>456</text>
        </field>
    </member>
</members>
期望输出:

Smith John 123
Bloggs  789
Jones Jane 456
实际输出,将Bloggs的名字显示为John而不是空白:

Smith John 123
Bloggs John 789
Jones Jane 456
我可以通过在每个成员迭代之前设置姓氏、名字和id变量来避免这种情况:

for member in y:
    surname = ''
    firstname = ''
    id = ''

    fields = member.findall("field")
    for field in fields:
        if field.get('name') == 'surname':
            surname = field.find('text').text
        if field.get('name') == 'firstname':
            firstname = field.find('text').text
        if field.get('name') == 'id':
            id = field.find('text').text

    print(surname, firstname, id)
这将产生所需的结果:

Smith John 123
Bloggs  789
Jones Jane 456

然而,这感觉有点像是一种变通方法——有没有其他更具python风格的方法来实现这一点

这些东西最好独立于自己的功能。
是的,当您需要空字段时,您应该首先重置它们。实际上,您拥有的字段是可以读取的。但是如果你真的想,你可以使用三元表达式

for member in y:
    fields = member.findall("field")
    for field in fields:
        surname = field.find('text').text if field.get('name') == 'surname' else ''
        firstname = field.find('text').text if field.get('name') == 'firstname' else ''
        id = field.find('text').text if field.get('name') == 'id' else ''

    print(surname, firstname, id)

也许通过使用dict理解将数据放入dict中更容易实现这一点。这样,dict将始终被覆盖,即使它完全为空,因为成员中没有字段:

for member in root.findall("member"):
    data = {field.get("name") : field.find("text").text for field in member.findall("field")}
    print(
        data.get("surname", "(no surname"),
        data.get("firstname", "(no firstname)"),
        data.get("id", "(no id")
    )
=>


是什么让你觉得这不是pythonic的?用这种方式重置变量感觉有点“手工”。(我不确定我到底是什么意思!)我的第一个想法是,我可能需要更好地理解变量范围。
for member in root.findall("member"):
    data = {field.get("name") : field.find("text").text for field in member.findall("field")}
    print(
        data.get("surname", "(no surname"),
        data.get("firstname", "(no firstname)"),
        data.get("id", "(no id")
    )
Smith John 123
Bloggs (no firstname) 789
Jones Jane 456