2012-01-19 83 views
3

我是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, ...],则仅“估计”一行(预计日期的预定行)。

任何想法我在这里失踪?谢谢!

+4

你的“继续”声明实际上并没有做任何事情;在try块的最后一行执行后,for循环自然会继续。 –

+0

你能接受这些答案吗?他们都写得很好。 –

回答

3

的问题是在该行:

fixdata = data[-1] 

实际上并没有复制数据,它只是复制参考的数据。 fixdata最终指向列表中的原始元素,所以当你然后做

fixdata[10] = 'estimated' 

它改变了原来的数据。

要的数据实际上复制,试试这个:

fixdata = data[-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将成为自己的列表,您可以更改独立于原始的元素。你原来的代码示例

+0

谢谢!看起来这是个窍门。 – Adam

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 
    

全部放在一起,我会写代码更是这样的:

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']) 
+0

如果至少有一个'data.append'没有成功,我不明白*(在第n.4点)*'data [-1]'是如何被调用的。 –

+0

如果第一个'WUF.getwx()'调用引发异常,那么当异常处理程序执行时'data'仍然是空的 –

+0

噢,是的,你是对的。我不知道为什么,但我认为'除了像'else'那样。感谢您的澄清+1 :) –