關(guān)于python中remove的一些坑小結(jié)
前幾天,使用python時遇到這么一個需求,刪除一個列表中值為1的元素。我尋思著使用remove方法,但是remove方法只會刪除第一個,于是我使用for循環(huán)去刪除。代碼和運(yùn)行結(jié)果如下:
當(dāng)時這個結(jié)果讓我很懵逼,為什么1沒有被刪除完?查了資料發(fā)現(xiàn),是for循環(huán)搗的鬼。因為for循環(huán)實際是循環(huán)的列表下標(biāo)(索引),同時由于列表的可變性,每一次刪除一個元素,列表的長度就會發(fā)生變化,元素的索引也會發(fā)生變化。這里來具體分析一下這段代碼:
第一次循環(huán),循環(huán)索引為0,此時索引為0的元素是1,滿足條件,因此mylist中的第一個1被刪除,此時mylist變?yōu)閇1,2,1,1,3,4];
第二次循環(huán),循環(huán)索引為1,此時新列表中,索引為1的元素是2,不滿足條件,mylist仍然為[1,2,1,1,3,4];
第三次循環(huán),循環(huán)索引為2,此時列表中,索引為2的元素是1,滿足條件,remove方法會再次刪除一個1,但是remove會刪除第一次出現(xiàn)的1(即刪除索引為0的那個1),因此列表變?yōu)閇2,1,1,3,4];
第四次循環(huán),循環(huán)索引為3,新列表中,索引為3的元素是3,不滿足條件,mylist仍然為[2,1,1,3,4];
第五次循環(huán),循環(huán)索引為4,此時列表中,索引為4的元素是4,不滿足條件,mylist仍然為[2,1,1,3,4];
此時,由于新列表長度為5,于是循環(huán)結(jié)束。
下面的截圖結(jié)果能夠很直觀的看出來。
至此,如果是這樣的一段代碼,結(jié)果應(yīng)該是怎樣?
最終mylist=['b','d'],怎么樣,和你計算的值是否一樣?
回到最初的需求,要怎樣才能刪除所有的1,這里可以使用deepcopy來復(fù)制一份,之后一個列表用于循環(huán),一個用于移除值。代碼和結(jié)果如下:
這樣就可以實現(xiàn)刪除列表中的所有值為1的元素。這里可能有人會問,為什么不直接將l1賦值給一個變量,即l2=l1,這里涉及到引用和深淺復(fù)制的問題,因此不在此處解答
附:Python列表的remove方法的注意事項
為何沒有刪除列表中的全部元素?
解釋:
按照執(zhí)行順序,第一個空格被刪除之后,后面的元素會前移(變成['空格','空格','12','23']),指針下一次會指向新列表的第二個元素(即初始狀態(tài)的第三個空格),從而初始狀態(tài)的第二個空格被跳過了,初始第三個空格被刪除,接著后面的元素又再次前移(變成['空格','12','23']),指針指向新列表的第三個元素,即初始狀態(tài)的第5個元素23,然后23被刪除了,因此只剩下['空格','12']
如果想排除初始列表中的部分元素,如何實現(xiàn)?
由上面的情況知道,在遍歷列表的同時對列表執(zhí)行刪除操作,會造成意外的結(jié)果,那么對初始列表進(jìn)行遍歷,對初始的列表的副本執(zhí)行刪除操作呢?
以上結(jié)果顯示,沒有得到預(yù)期效果。為什么?
問題出在copy=ls這一句,這里僅僅是使得copy與ls指向了同一片內(nèi)存(即淺拷貝,shallow copy),并沒有執(zhí)行【開辟一片新內(nèi)存,并且ls內(nèi)存中的內(nèi)容復(fù)制到新內(nèi)存,然后使copy指向新開辟的內(nèi)存,即深拷貝,deep copy】這一系列操作。因此對copy執(zhí)行的remove操作,和對遍歷ls列表,實質(zhì)上還是都是針對同一片內(nèi)存進(jìn)行操作,因此結(jié)果上一個例子類似。
若想解決這一問題,有3個辦法法:
(1)
ls=[' ',' ',' ','12','23','abc','aa'] copy=[' ',' ',' ','12','23','abc','aa']
這一辦法對于已知列表的所有元素,且元素數(shù)量較少,結(jié)構(gòu)較簡單時可行,其他情況下不可行。
(2)引入copy模塊的deepcopy方法:
(3)另外準(zhǔn)備一個空列表,遍歷初始列表時,將符合條件的元素逐一加入到空列表當(dāng)中(利用列表的append方法)。
這種方法,思路上與remove方法相反,但執(zhí)行的操作差不多,時間復(fù)雜度也與remove方法差不多,無需引入copy模塊。
另外,對于列表的remove方法,python基礎(chǔ)教程第二版給出的說明是:
remove方法用于移除列表中某個值的第一個匹配項:
>>>x=['to','be','or','not','to','be'] >>>x.remove('be') >>>x ['to','or','not','to','be']
到此這篇關(guān)于python中remove的一些坑小結(jié)的文章就介紹到這了,更多相關(guān)python中remove的坑內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python無限生成不重復(fù)(字母,數(shù)字,字符)組合的方法
今天小編就為大家分享一篇python無限生成不重復(fù)(字母,數(shù)字,字符)組合的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-12-12python程序中調(diào)用其他程序的實現(xiàn)
本文主要介紹了python程序中調(diào)用其他程序的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-02-02python數(shù)據(jù)結(jié)構(gòu)之搜索講解
這篇文章主要介紹了python數(shù)據(jù)結(jié)構(gòu)之搜索講解,搜索是指從元素集合中找到某個特定元素的算法過程。搜索過程通常返回?True?或?False,?分別表示元素是否存在,下面一起來了解文章的詳細(xì)內(nèi)容吧,希望對你有所幫助2021-12-12Pandas探索之高性能函數(shù)eval和query解析
這篇文章主要介紹了Pandas探索之高性能函數(shù)eval和query解析,小編覺得還是挺不錯的,這里分享給大家,供需要的朋友參考。2017-10-10查找適用于matplotlib的中文字體名稱與實際文件名對應(yīng)關(guān)系的方法
這篇文章主要介紹了查找適用于matplotlib的中文字體名稱與實際文件名對應(yīng)關(guān)系的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01