我在 python 中使用串列,我需要洗掉非真值。
有人可以解釋為什么我在這里得到索引超出范圍錯誤:
for n in range(len(lst)-1): #index outside the range
if not bool(lst[n]):
lst.pop(n)
return lst
它有點像 while 回圈
def compact(lst):
while n < len(lst):
if not bool(lst[n]):
lst.pop(n)
n =1
print(n)
return lst
但在這種情況下回圈會跳過一些專案。
函式呼叫如下:
compact([0, 1, 2, '', [], False, (), None, 'All done'])
uj5u.com熱心網友回復:
當你洗掉一個元素時,它之后的所有元素都會重新編號:第n 1th 個元素變成第 th 個元素,等等。但無論如何n你都會前進到下一個。n這就是您跳過某些元素的原因。
在第一個片段中,您預先構建了要迭代的索引串列;但隨著串列的縮短,后面的一些索引將不復存在。
在第二個片段中,您在每次迭代中與串列的實際長度進行比較,因此您永遠不會得到無效的索引。
另請注意,bool無論何時評估條件,都不需要它,因為它已隱式應用于此類背景關系。
為了正確執行此操作,您有兩種選擇:
從串列末尾向后迭代。如果洗掉一個元素,它前面的元素不會重新編號。
for n in range(len(lst) - 1, -1, -1): if not lst[n]: lst.pop(n)使用該
while方法,確保增加(移近串列末尾)或洗掉元素(移近串列末尾);從來沒有同時。這將確保不會跳過。nnnn = 0 while n < len(lst): if not lst[n]: lst.pop(n) else: n = 1
第三種選擇是完全避免索引回圈,并且更像 python 方式,使用帶有過濾條件的推導生成新串列,或者filter.
new_lst = list(filter(bool, lst))
或者
new_lst = [e for e in lst if e]
或者,如果您真的想更改原始串列,請像這樣替換其內容:
lst[:] = filter(bool, lst)
uj5u.com熱心網友回復:
索引超出范圍錯誤:
lst.pop(n)這將從串列中彈出元素,但for n in range(len(lst)-1)仍會回圈遍歷 lst,假設長度與原始元素相同。
為了避免以相反順序從最后一個索引開始回圈,這樣即使在 pop 值之后仍將存在于尚未讀取的索引。
def compact(lst):
for n in range(len(lst)-1,-1,-1):
if not bool(lst[n]):
lst.pop(n)
return lst
ls = [0, 1, 2, '', '',[], False, (), None, 'All done','']
print(compact(ls))
# Output:
# [1, 2, 'All done']
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/534361.html
標籤:Python列表
