2016-10-19 140 views
1

Goodmorning, 我剛剛在python中編寫了這個程序,並且這個IndexError一直顯示出來。我不知道如何解決它,我甚至嘗試通過使用while循環,但沒有任何改變...我希望有人可以幫助我解決這個問題!IndexError:「pop index out of range」with for循環

這是我的代碼,它應該檢查兩個列表(la,lb)的對象的長度,並且:如果字符串比lb字符串長,則從la列表中刪除字符串,反之亦然。如果它們的長度相同,它必須刪除這兩個字符串。

def change(l1,l2): 
    la1 = l1[:] 
    la2 = l2[:] 
    i = 0 
    for i in range(len(la1)): 
     if la1[i] == la2[i]: 
      l1.pop(i) 
      l2.pop(i) 
     elif la1[i] > la2[i]: 
      l2.pop(i) 
     elif la2[i] > la1[i]: 
      l1.pop(i) 
+2

如果列表爲空,'list.pop'將引發'IndexError'。 –

+1

你沒有比較字符串長度,只是字符串。 –

+0

你有(短)使用示例嗎? –

回答

2

假設你的名單長度相等

正如已指出,在評論中,IndexError發生因您的名單長度改變,當你pop()的項目。

由於您在for循環中使用range(len(l))循環遍歷列表,因爲循環在每個完成的循環後未更新,所以最終會遇到超出範圍的索引。

一個例子,你可以嘗試很輕鬆地自己:

l = [1,2,3,4,5,6,7,8,9,10] 

for i in range(len(l)): 
    l.pop(i) 
    print("Length of list", len(l)) 

不要通過調用for循環print(range(len(l))混淆自己 - 這會給你一個更新的範圍,但有誤導之嫌。 for循環中的range僅被調用一次,因此在迭代過程中不會更新。

一種不同的方法

而是與指數的工作,請嘗試使用zip(),建設一個新的列表,而不是改變現有的。

def change(l1, l2): 
    new_l1 = [] 
    new_l2 = [] 
    for a, b in zip(l1, l2): 
     if len(a) == len(b): 
      continue # do nothing 
     elif len(a)<len(b): 
      new_l2.append(b) 
     elif len(a)>len(b): 
      new_l1.append(a) 
    return new_l1, new_l2 

這種做法,本質上,生成您創建使用pop()相同的列表,同時避免了指數的使用。

請注意,zip()一旦到達兩個可迭代中較小的一個,就會停止。如果列表的長度可能不相同,並且您想迭代,直到兩個迭代中最長的迭代完全迭代,請使用zip_longest()。但我不認爲這是你在這種情況下需要的。

其他注意事項

,如果你是使用下面的代碼在你的list迭代也將碰到一個問題:

l = [i for i in range(10)] 
for item in l: 
    l.remove(item) 
>>>[1, 3, 5, 7, 9] 

從本質上講,它是不可取的迭代任何iterable,同時更改它。這可能導致從拋出的Exception到沉默的意外行爲。

我知道你是通過循環複製避免這種情況,我只是想爲後代添加這個。

0

您可以向後遍歷列表,這樣,當你從列表中刪除一個項目,你有沒有檢查尚未不會受到影響

def f(a, b): 
    l = len(a) if len(a)<len(b) else len(b) 
    for i in range(l): 
     j = l-i-1 
     la, lb = len(a[j]), len(b[j]) 
     if la<lb: a.pop(j) 
     elif lb<la: b.pop(j) 
     else: a.pop(j), b.pop(j) 
    return a, b 

PS我這兒待忠實於元素的索引你的問題陳述,而不是你的實現重新比較基於字符串的長度。