2016-10-19 283 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我这儿待忠实于元素的索引你的问题陈述,而不是你的实现重新比较基于字符串的长度。