Python中列表的陷阱

作爲python的初學者,在做決策樹算法的程序時一個有關列表刪除的問題困擾了一天。今天在博客裏寫出來,希望大家也可以避免如此的問題。

下面是代碼綱要:

def read_txt(filename):#定義了一個讀txt文件的函數,這個函數的作用是將一個txt的表格轉化成一個python列表。

它是一個嵌套的列表,下面隨便粘幾行:

['54', ' ?', ' 180211', ' Some-college', ' 10', ' Married-civ-spouse', ' ?', ' Husband', ' Asian-Pac-Islander', ' Male', ' 0', ' 0', ' 60', ' South', ' >50K']

['31', ' Private', ' 84154', ' Some-college', ' 10', ' Married-civ-spouse', ' Sales', ' Husband', ' White', ' Male', ' 0', ' 0', ' 38', ' ?', ' >50K']

這個列表中會有很多行用' ?'標記的字段,會影響我後續的處理。所以我採用一種辦法,那就是對於包含‘?’的行全部刪除,接下來的子函數就是這個作用。

def computeNa(items):
#detect missing value in list and handle it
for item in items:
if item.count(' ?') > 0:
items.remove(item)
return items

短短的幾行代碼,意思很清楚。接下來:

fileName = "C:\data.txt"

data_list = read_txt(filename)

data_filtered = computeNa(data_list)

在代碼的測試階段我發現

print len(data_list) #得到結果32561

print len(data_filtered)  #得到結果30310

我以爲這個函數很好的處理了missing value,後續處理才發現原來data_filtered還有‘?’存在。你知道這是爲什麼嗎?

接下來我開始處理這個bug:

我又加了一句data_filtered2 = computeNa(data_filtered) 然後print len(data_filtered2) #得到結果30162。奇怪的是這次data_list中的missing value全沒了,所以我得到結論,要想過濾掉data_list中的missing value必須過濾兩次。好像可以說的通一樣,但是我知道這是一個bug。後來我想了很多辦法都沒有搞定這個問題,我甚至懷疑這是python的一個巨大漏洞。就這樣糾結了一天,就在剛剛我看python提供的documentation發現了這樣一句話“If you need to modify the sequence you are iterating over while inside the loop (for example to duplicate selected items), it is recommended that you first make a copy. Iterating over a sequence does not implicitly make a copy. The slice notation makes this especially convenient:”(https://docs.python.org/2/tutorial/controlflow.html#for-statements)。

意思是說,如果想在一個循環中改變一個列表中的內容你最好爲這個列表做一個複製,所以只需要把“for item in items:”改爲“for item in items[:]:”,這樣這個bug就解決了。希望大家在以後用列表的時候注意這點。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章