2010-08-16 91 views
0

我有一個列表的列表,看起來像:Python列表幫助

floodfillque = [[1,1,e],[1,2,w], [1,3,e], [2,1,e], [2,2,e], [2,3,w]] 

for each in floodfillque: 
    if each[2] == 'w': 
     floodfillque.remove(each) 
    else: 
     tempfloodfill.append(floodfillque[each[0+1][1]]) 

這是一個簡單的,但我認爲代碼的相關部分。

floodfillque[each[0+1]]部分是否執行我認爲正在執行的操作,並在該位置處取值並將其添加到該位置?爲什麼我想問的原因是我得到這個錯誤:

TypeError: 'int' object is unsubscriptable

而且我覺得我誤解是什麼代碼實際上做或做錯了。

+2

修改循環中迭代的序列是不安全的:http://docs.python.org/tutorial/controlflow.html#for-statements – stephan 2010-08-16 15:34:00

回答

5

除了在你的代碼中的錯誤,其他答案已經發現,至少有一個以上:

for each in floodfillque: 
    if each[2] == 'w': 
     floodfillque.remove(each) 

不添加或從你的循環很容器中移除項在。雖然這樣的錯誤通常只會針對特定類型的容器(不包括列表)進行診斷,但對於列表來說,這同樣可怕 - 它最終會通過跳過一些項目或者查看一些項目來更改您的預期語義。

如果不能顯着改變,並(通過建立一個新的,獨立的容器,而不是你在循環的一個普遍碴)提高你的邏輯,最簡單的解決方法通常循環上的副本容器必須改變:

for each in list(floodfillque): 

現在,你的添加和移除不會改變你實際上在循環(因爲你要循環的是一個副本,「快照」,進行一次和所有在循環的開始),所以你的語義將按預期工作。

你要改變floodfillque具體做法也有性能錯誤 - 它的行爲平方,而合理的邏輯(建設一個新的容器,而不是改變原來的一個)會表現得線性。但是,如果不將代碼從當前不太好的邏輯重構爲新的,有根據的代碼,那麼該錯誤就很難修復。

3

Does the floodfillque[each[0+1] part do what I think it is doing and taking the value at that location and adding one to it or no?

不,這聽起來像你想each[0] + 1

無論哪種方式,你得到的錯誤是因爲你試圖把一個整數的第二個項目... each[0+1][1]解析each[1][1]這可能是這樣的3[1],這沒有任何意義。

+0

我有一個系統來檢查以確保不會發生。但是,也許是因爲我正在修改列表,我正在循環瀏覽會導致此問題發生? – 2010-08-16 15:51:42

4

這裏發生的事情:

在循環的第一次迭代,each[1, 1, 'e']。由於each[2] != 'w',執行else

else中,您取each[0+1][1],與(each[0+1])[1]相同。 each[0+1]1,所以你在做(1)[1]int對象不能被索引,這是什麼引發了錯誤。

+0

好的,那麼解決方案是什麼?如果我想每個[0] + 1我可以這樣做嗎? – 2010-08-16 15:53:36

+1

解決方案是什麼?我只是指出爲什麼引發異常。您的問題太不清楚,無法給出任何其他答案。 – habnabit 2010-08-16 15:55:21

+0

基本上,我如何將1添加到列表索引。 – 2010-08-16 15:56:31

3

其他海報是正確的。但是,此代碼中存在另一個錯誤,那就是您在迭代時正在修改floodfillque。這會導致問題,因爲Python內部維護一個計數器來處理循環,並且刪除元素不會修改計數器。

的安全的方式做,這就是循環的循環的副本:([ : ]是Python的符號爲複印件)

1

這是我所理解的NoahClark的意圖:

  1. 刪除這些子列表,其第三個要素是「W」
  2. 對於剩餘的子表,加1到第二個項目

如果這是這樣,以下將做:

# Here is the original list 
floodfillque = [[1,1,'e'], [1,2,'w'], [1,3,'e'], [2,1,'e'], [2,2,'e'], [2,3,'w']] 

# Remove those sublists which have 'w' as the third element 
# For the rest, add one to the second element 
floodfillque = [[a,b+1,c] for a,b,c in floodfillque if c != 'w'] 

這個解決方案工作正常,b它不是最有效的:它創建一個新的列表,而不是修補原來的一個。