基於Python中Remove函式的用法討論
前幾天在進行寫程式時碰到這樣一個問題
a=['a','b','c','d']
b=['c','d','e','f']
需要將陣列a中元素,在陣列b中出現過都刪除。第一次寫出程式如下:
a=['a','d'] b=['c','f'] for x in a: if x in b: a.remove(x) print (a)
最後的輸出結果為
出現這樣的結果,當時感覺很詫異。但立馬細細一想,立馬明白了其中的原因。
當x='c'時,此時滿足if條件語句,執行if下的語句:a.remove(x),也就是將'c'元素從a陣列中刪除。
刪除之後,remove函式並沒有執行結束。而是將a陣列中索引號大於刪除元素索引號的所有元素依次前一位。
此時,x指向a[2],a陣列當前的狀態為:['a','d'],a[2]中儲存的為元素'd'。
remove函式返回後,繼續執行for迴圈,x指向陣列的下一個索引。
因此導致了'd'元素沒有與陣列b進行比較。
後續,將程式進行了如下修改:
a=['a','d'] c=['a','f'] for x in a: if x in b: c.remove(x) print (c)
程式執行結果如下:
雖然問題不是很難,但是這個細節問題一定要把握。
補充知識:Python列表的remove方法的注意事項
為何沒有刪除列表中的全部元素?
解釋:
按照執行順序,第一個空格被刪除之後,後面的元素會前移(變成['空格','空格','12','23']),指標下一次會指向新列表的第二個元素(即初始狀態的第三個空格),從而初始狀態的第二個空格被跳過了,初始第三個空格被刪除,接著後面的元素又再次前移(變成['空格','23']),指標指向新列表的第三個元素,即初始狀態的第5個元素23,然後23被刪除了,因此只剩下['空格','12']
如果想排除初始列表中的部分元素,如何實現?
由上面的情況知道,在遍歷列表的同時對列表執行刪除操作,會造成意外的結果,那麼對初始列表進行遍歷,對初始的列表的副本執行刪除操作呢?
以上結果顯示,沒有得到預期效果。為什麼?
問題出在copy=ls這一句,這裡僅僅是使得copy與ls指向了同一片記憶體(即淺拷貝,shallow copy),並沒有執行【開闢一片新記憶體,並且ls記憶體中的內容複製到新記憶體,然後使copy指向新開闢的記憶體,即深拷貝,deep copy】這一系列操作。因此對copy執行的remove操作,和對遍歷ls列表,實質上還是都是針對同一片記憶體進行操作,因此結果上一個例子類似。
若想解決這一問題,有3個辦法法:
(1)
ls=[' ',' ','23','abc','aa']
copy=[' ','aa']
這一辦法對於已知列表的所有元素,且元素數量較少,結構較簡單時可行,其他情況下不可行。
(2)引入copy模組的deepcopy方法:
Python列表的remove方法的注意事項
(3)另外準備一個空列表,遍歷初始列表時,將符合條件的元素逐一加入到空列表當中(利用列表的append方法)。
這種方法,思路上與remove方法相反,但執行的操作差不多,時間複雜度也與remove方法差不多,無需引入copy模組。
另外,對於列表的remove方法,python基礎教程第二版給出的說明是:
remove方法用於移除列表中某個值的第一個匹配項:
>>>x=['to','be','or','not','to','be'] >>>x.remove('be') >>>x ['to','be']
以上為個人經驗,希望能給大家一個參考,也希望大家多多支援我們。如有錯誤或未考慮完全的地方歡迎留言討論,望不吝賜教。