python list遍历删除_Python中list循环遍历删除数据的正确方法
前言
初學(xué)Python,遇到過這樣的問題,在遍歷list的時(shí)候,刪除符合條件的數(shù)據(jù),可是總是報(bào)異常,代碼如下:
num_list = [1, 2, 3, 4, 5]
print(num_list)
for i in range(len(num_list)):
if num_list[i] == 2:
num_list.pop(i)
else:
print(num_list[i])
print(num_list)
會(huì)報(bào)異常:IndexError: list index out of range
原因是在刪除list中的元素后,list的實(shí)際長(zhǎng)度變小了,但是循環(huán)次數(shù)沒有減少,依然按照原來list的長(zhǎng)度進(jìn)行遍歷,所以會(huì)造成索引溢出。
于是我修改了代碼如下:
num_list = [1, 2, 3, 4, 5]
print(num_list)
for i in range(len(num_list)):
if i >= len(num_list):
break
if num_list[i] == 2:
num_list.pop(i)
else:
print(num_list[i])
print(num_list)
這回不會(huì)報(bào)異常了,但是打印結(jié)果如下:
[1, 2, 3, 4, 5]
1
4
5
[1, 3, 4, 5]
[Finished in 0.441s]
雖然最后,list中的元素[2]確實(shí)被刪除掉了,但是,在循環(huán)中的打印結(jié)果不對(duì),少打印了[3]。
思考了下,知道了原因,當(dāng)符合條件,刪除元素[2]之后,后面的元素全部往前移,于是[3, 4, 5]向前移動(dòng),那么元素[3]的索引,就變成了之前[2]的索引(現(xiàn)在[3]的下標(biāo)索引變?yōu)?了),后面的元素以此類推。可是,下一次for循環(huán)的時(shí)候,是從下標(biāo)索引2開始的,于是,取出了元素[4],就把[3]漏掉了。
把代碼修改成如下,結(jié)果一樣,絲毫沒有改觀:
num_list = [1, 2, 3, 4, 5]
print(num_list)
for item in num_list:
if item == 2:
num_list.remove(item)
else:
print(item)
print(num_list)
既然知道了問題的根本原因所在,想要找到正確的方法,也并不難,于是我寫了如下的代碼:
num_list = [1, 2, 3, 4, 5]
print(num_list)
i = 0
while i < len(num_list):
if num_list[i] == 2:
num_list.pop(i)
i -= 1
else:
print(num_list[i])
i += 1
print(num_list)
執(zhí)行結(jié)果,完全正確:
[1, 2, 3, 4, 5]
1
3
4
5
[1, 3, 4, 5]
[Finished in 0.536s]
我的做法是,既然用for循環(huán)不行,那就換個(gè)思路,用while循環(huán)來搞定。每次while循環(huán)的時(shí)候,都會(huì)去檢查list的長(zhǎng)度(i < len(num_list)),這樣,就避免了索引溢出,然后,在符合條件,刪除元素[2]之后,手動(dòng)把當(dāng)前下標(biāo)索引-1,以使下一次循環(huán)的時(shí)候,通過-1后的下標(biāo)索引取出來的元素是[3],而不是略過[3]。
當(dāng)然,這還不是最優(yōu)解,所以,我搜索到了通用的解決方案:1、倒序循環(huán)遍歷;2、遍歷拷貝的list,操作原始的list。
1、倒序循環(huán):
num_list = [1, 2, 3, 4, 5]
print(num_list)
for i in range(len(num_list)-1, -1, -1):
if num_list[i] == 2:
num_list.pop(i)
else:
print(num_list[i])
print(num_list)
執(zhí)行結(jié)果完全正確。那么,為何正序循環(huán)時(shí)刪除就有問題,而倒序循環(huán)時(shí)刪除就ok?額。。。。。。言語難表,還是畫個(gè)丑圖出來吧。
1)正序循環(huán)時(shí)刪除:
刪除元素[2]之后,下一次循環(huán)的下標(biāo)索引為2,但此時(shí),里面存放的是[4],于是就把[3]給漏了。
2)倒序循環(huán)時(shí)刪除
刪除元素[2]后,[3, 4, 5]往前擠,但是沒關(guān)系,因?yàn)橄乱淮窝h(huán)的下標(biāo)索引為0,里面存放的是[1],所以正是我們所期望的正確的元素值。
2、遍歷拷貝的list,操作原始的list
num_list = [1, 2, 3, 4, 5]
print(num_list)
for item in num_list[:]:
if item == 2:
num_list.remove(item)
else:
print(item)
print(num_list)
原始的list是num_list,那么其實(shí),num_list[:]是對(duì)原始的num_list的一個(gè)拷貝,是一個(gè)新的list,所以,我們遍歷新的list,而刪除原始的list中的元素,則既不會(huì)引起索引溢出,最后又能夠得到想要的最終結(jié)果。此方法的缺點(diǎn)可能是,對(duì)于過大的list,拷貝后可能很占內(nèi)存。那么對(duì)于這種情況,可以用倒序遍歷的方法來實(shí)現(xiàn)。
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)我們的支持。
本文標(biāo)題: Python中l(wèi)ist循環(huán)遍歷刪除數(shù)據(jù)的正確方法
本文地址: http://www.cppcns.com/jiaoben/python/271627.html
總結(jié)
以上是生活随笔為你收集整理的python list遍历删除_Python中list循环遍历删除数据的正确方法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python升级matplotlib包_
- 下一篇: 请思考并描述下面python语句的输出结