for循环中的Python异常处理

时间:2012-01-19 21:37:47

标签: python

我是Python的新手,也是一般编程人员。虽然我认为这个问题可能与我使用异常处理有关,但也可能是由于普遍缺乏理解!

for i in range(0, len(dates)):
    try:
        data.append(WUF.getwx(location[j], dates[i])[1])
        continue
    except xml.etree.ElementTree.ParseError:
        #copy last good row of data and use it for the missing day
        fixdata = data[-1] #[1,2,3,4,5,6,7,8,9,10,11]
        fixdata[10] = 'estimated'
        data.append(fixdata)

当我按照编写的方式运行代码时,我在data中得到2条“估计”行。一个用于上一个日期,一个用于估计的日期。如果我将fixdata变量更改为[1, 2, 3, 4, 5, ...],则只会估算一行(估计日期的预期行)。

知道我在这里缺少什么吗?谢谢!

3 个答案:

答案 0 :(得分:3)

问题在于:

fixdata = data[-1]

实际上并不复制数据,它只将引用复制到数据中。 fixdata最终指向列表中的原始元素,因此当您执行

fixdata[10] = 'estimated'

它会更改原始数据。

要实际复制数据,请尝试以下操作:

fixdata = data[-1][:]

[:]复制整个列表,这是我认为您正在尝试做的事情。

答案 1 :(得分:1)

听起来您正在将列表附加到data列表中 - 创建“列表列表”。

那很好 - 我确定这是你打算做的。但是在您的异常处理程序中,您实际上是在修改现有数据:

fixdata = data[-1]

此行将引用分配到datafixdata的最后一行。此时,fixdatadata[-1] 是同一个对象。所以,当你这样做时:

fixdata[10] = 'estimated'

然后,您正在“修复”的列表仍在data列表中,并且被名称fixdata引用。两个名字,一个在记忆中的对象。

当你再次追加时,用

data.append(fixdata)

你仍然没有复制它;现在,您实际上有两个对data列表中同一个对象的引用。这就是为什么看起来你有两条'估计'线 - 它们是同一个对象。

你真正想做的是复制最后一行,而不仅仅是对它的引用。将您的代码更改为:

for i in range(0, len(dates)):
    try:
        data.append(WUF.getwx(location[j], dates[i])[1])
        continue
    except xml.etree.ElementTree.ParseError:
        #copy last good row of data and use it for the missing day                 
        fixdata = data[-1][:] #[1,2,3,4,5,6,7,8,9,10,11]
        fixdata[10] = 'estimated'                
        data.append(fixdata)

语法列表[:]是“此列表的每个元素”的简写,用作快速复制操作。然后fixdata将是它自己的列表,你可以独立改变原始元素。

答案 2 :(得分:1)

关于原始代码示例的更多评论(超出了您的问题范围)

  1. 除了索引回日期列表之外,你永远不会真正使用i变量。 Python的优势之一是它的迭代器:你可以直接在列表中的项目上迭代你的for循环,而不必计算它们并使用索引变量:

    for date in dates:
    
  2. 您的continue语句实际上没有做任何事情。 continue告诉解释器立即完成for循环的迭代,并立即开始下一次迭代。在这种情况下,continue语句之后没有语句,因此循环将自然地继续,而不会被告知。

  3. 确实没有必要在两个语句中构建fixdata变量,将其附加到第三个,然后丢弃它(我们丢弃fixdata变量,而不是其内容)你可以这样简洁地做到这一点:

    data.append(data[-1][:10] + ['estimated'])
    

    在一行中,这会将最后一行的前10个元素复制到一个新列表中,将(非常短的)列表['估计']添加到结尾,然后附加它。

  4. 如果您的第一行抛出异常,您的代码将遇到问题 - 在这种情况下,您将无法访问data[-1] - 尝试这样做会抛出另一个异常,它将传播。最好这样防范:

    except xml.etree.ElementTree.ParseError:
        if data:
            # do something
    
  5. 总而言之,我会更像这样编写代码:

    for date in dates:
        try:
            data.append(WUF.getwx(location[j], date)[1])
        except xml.etree.ElementTree.ParseError:
            # as long as we've parsed at least one good row
            if data:
                # copy last good row of data and use it for the missing day
                data.append(data[-1][:10] + ['estimated'])