python IndexError:“pop index out of range”with a for loop

xurqigkl  于 2023-09-29  发布在  Python
关注(0)|答案(4)|浏览(180)

如何解决这个IndexError?我尝试使用while循环,但没有任何变化。
下面是我的代码,它应该检查两个列表(lalb)的对象的长度,如果字符串比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)
5n0oy7gb

5n0oy7gb1#

假设您的列表长度相等

正如在评论中指出的,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的同时迭代任何iterable是不可取的。这可能会导致从抛出Exception到静默的意外行为。
我知道你是通过循环复制来避免这一点,我只是想为后代添加这个。

gywdnpxw

gywdnpxw2#

您可以向后遍历列表,这样当您从列表中删除一个项目时,尚未检查的元素的索引将不会受到影响

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我忠实于你的问题陈述,而不是你的实现,基于字符串长度的比较。

oyxsuwqo

oyxsuwqo3#

如果你想遍历一个列表并清空它
但不希望弹出索引错误使用此:

lst = [ 1, 4, 56, 2, 4 , 12,  6, 89 ,11, 0]
i =0
while len(lst) != 0:
    lst.pop(0)
    i+=1
print(lst)
irlmq6kh

irlmq6kh4#

如果你指定了IndexError的索引,并且列表小于你的索引,那么弹出抛出IndexError

>>> [100].pop(1)

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: pop index out of range

相关问题