【问题标题】:Reset variable when using for loop in python在python中使用for循环时重置变量
【发布时间】:2019-02-01 12:49:24
【问题描述】:

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

我遇到的问题是,如果其中一个成员缺少元素(与元素中的缺失数据相反),那么我当前的代码会维护上次迭代(成员)的变量值。

我的数据:

<?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>

我的代码:

tree = ET.parse('mydata.xml')
root = tree.getroot()
y = root.findall('member')
for member in y:
    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

实际输出,将 Bloggs 的名字显示为 John 而不是空白:

Smith John 123
Bloggs John 789
Jones Jane 456

我可以通过在每次成员迭代之前设置 surname、firstname 和 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

但这感觉有点解决方法 - 是否有替代的、更 Pythonic 的方法来实现这一点?

【问题讨论】:

  • 是什么让你认为这不是 Python 的?
  • 以这种方式重置变量感觉有点“手动”。 (虽然我不确定我的真正意思!)我的第一个想法是我可能需要更好地理解变量范围。

标签: python xml python-3.x elementtree


【解决方案1】:

你所拥有的实际上是相当好的和可读的。但是如果你真的想要你可以使用三元表达式

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)

【讨论】:

    【解决方案2】:

    也许这更容易通过使用字典理解将数据放入字典中来实现。这样 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")
        )
    

    =>

    Smith John 123
    Bloggs (no firstname) 789
    Jones Jane 456
    

    【讨论】:

      【解决方案3】:

      这些东西可能更好地隔离到自己的功能中。 是的,当你想要空字段时,你应该先重置它们

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-05-05
        • 2020-04-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-30
        • 1970-01-01
        相关资源
        最近更新 更多