首页 > 解决方案 > 我得到一个布尔值的“列表索引超出范围”,但当我在 for 和 if 循环中使用该布尔值时却没有?

问题描述

我写了一个函数,当给定一个整数列表时,当列表参数在某个地方包含一个 3 时返回 True 。这是我的代码:

def has_33(nums):
    for i,num in enumerate(nums):
        if nums[0]==3 and nums[1]==3:
            return True
        elif nums[i+1]==3 and (nums[i+2]==3 or nums[i]==3):
            return True
        else:
           return False 

这个函数要么返回 True 要么 False 即使我意识到

nums[i+1]

当循环到达最后一个索引时可能超出范围。

例如,如果我有一个定义为的列表nums=[1,3,4,5],则函数返回False。但是,当我单独运行时

nums[4]==1

我得到“IndexError:list index out of range”,我明白为什么,但我不明白为什么,在函数中,

nums[i+1] or (nums[i+2] or nums[i]==3)

当它到达列表的最后一个索引时不会抛出相同的错误?

标签: pythonlistif-statement

解决方案


该函数不会抛出 ,IndexError因为它永远不会到达列表的最后一个元素。

在第一次迭代中,如果评估条件 1 和 2,则两者都为 false,因此它进入else返回False,并且不再执行迭代。

如果您尝试使用,nums = [1, ]您实际上会得到 IndexError。您正在寻找的行为是return False在循环之外实现的:

def has_33(nums):
    for i, num in enumerate(nums):
        if nums[0]==3 and nums[1]==3:
            return True
        elif nums[i+1]==3 and (nums[i+2]==3 or nums[i]==3):
            return True
    return False   # <- this is outside the for loop

这样它循环 nums 列表中的每个元素。但是,您说得对,IndexError每次列表不包含一对 3 时,您的代码都会抛出一个。更安全的方法是跳过第一次迭代并查找元素及其先前的元素。更安全和更 Pythonic 的方法是zip在一行代码中使用该函数(我不想破坏解决方案,如果有兴趣回复评论)。


推荐阅读