2012-01-19 106 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 :) –