Python List 刪除內容 會重新 re-index

Python List 若將某一筆內容(Value)刪掉,那索引(Index)會自動重新計算,若使用 for + range() 再去 del,會造成一些錯誤。

Python List 刪除內容 會重新 re-index

假設有個 dlist 的 list,裡面塞三筆資料,然後,for 掃一輪遇到內容是 aa 的就移除,會遇到下述問題:

  1. 在 for + range() 的情況下,dlist 的 index 值遇到刪除就被修改
  2. for + range() 的 i(index) 值是一開始得到的數字,dlist re-index 後,對 for 的 i 來說並不知道
  3. 所以就會遇到 key 值找不到的問題

大概範例如下:

# data
dlist = []
dlist.append({'id': 'aa'})
dlist.append({'id': 'bb'})
dlist.append({'id': 'cc'})

# 因為我們用 range,list 並不是靠這個 index,所以移除會自動 re-index
del_list_index = []
for i in range(len(dlist)):
    print(dlist)
    print("0:" + dlist[0]['id'])
    print("1:" + dlist[1]['id'])
    print("2:" + dlist[2]['id'])
# output
# [{'id': 'aa'}, {'id': 'bb'}, {'id': 'cc'}]
# 0:aa
# 1:bb
# 2:cc

# List Delete
for i in range(len(dlist)):
    if dlist[i]['id'] == 'aa':
       print("del id:" + str(i) + dlist[i]['id'])
       del dlist[i] # 只要一刪除,後面 list 就會自動減少 and re-index
       print(dlist)
       print("0:" + dlist[0]['id'])
       print("1:" + dlist[1]['id'])
       print("2:" + dlist[2]['id']) # 遇到刪除後,會噴 error

# output for 1
[{'id': 'aa'}, {'id': 'bb'}, {'id': 'cc'}]
0:aa
1:bb
2:cc

# output for 2 (del 1 key)
[{'id': 'bb'}, {'id': 'cc'}]
0:bb
1:cc
Traceback (most recent call last):
      File "./foreach.py", line 62, in 
          print("2:" + dlist[2]['id'])
      IndexError: list index out of range

遇到上述的解法有幾種

這篇有提供作法:How do I remove a range (subsection) of a list in Python?

  • 下述二選一
    • all = all[:max(current - 2, 0)] + all[current:]
    • del all[max(current - 2, 0):current]

在這邊來寫第三種作法,直接先把要刪除的 key 存起來,最後掃完一輪後,再對存起來的 keys 掃一輪來刪掉 (不同 List 不會被影響,且需要由大刪到小)

dlist = []
dlist.append({'id': 'aa'})
dlist.append({'id': 'bb'})
dlist.append({'id': 'cc'})
dlist.append({'id': 'dd'})
dlist.append({'id': 'ee'})

del_list_index = []
for i in range(len(dlist)):
    if dlist[i]['id'] == 'bb' or dlist[i]['id'] == 'dd':
       print("del id:" + str(i) + dlist[i]['id'])
       del_list_index.append(i) # 先把要刪除的存著,等等在來刪除

del_list_index.reverse() # 由大排到小,由最大的開始刪除,就不需要擔心 re-index 問題
for index in del_list_index: # 刪除
    del dlist[index]
print(dlist)
# [{'id': 'aa'}, {'id': 'cc'}, {'id': 'ee'}]

作者: Tsung

對新奇的事物都很有興趣, 喜歡簡單的東西, 過簡單的生活.

發表迴響

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料