编写不会超出边界检查范围的if语句的最佳方法是什么?

时间:2019-08-03 21:48:01

标签: python if-statement indexoutofboundsexception

在for循环中,在没有超出范围的情况下检查列表中的上一个和下一个的最佳方法是什么? (请参见下面的代码)

比方说,我正在编写一个函数来检查每种颜色是否都与相同颜色的另一种颜色相邻,例如:

def colorChecker(colorList):
    colors = True
    for i in range(len(colorList)): #No editing this line
        if not ((i > 0 and colorList[i] == colorList[i-1]) or ((i < len(colorList)-1) and colorList[i] == colorList[i+1])):
            colors = False
    return colors

这给了我索引超出范围的异常...

我正在尝试检查索引是否超出范围,并在检查colorList[len(colorlist)+1]之前将其从if语句中反弹出来……但是显然,这不是正确的方法。你怎么会更好地写这个?

3 个答案:

答案 0 :(得分:3)

最好使用zip

遍历三组这样的元素
for prev,cur,nxt in zip(colorList, colorList[1:], colorList[2:]):
    if (prev == cur) or (cur == nxt):
         # Do something

答案 1 :(得分:2)

由于您要检查上一个和下一个元素,因此只需要从第二个元素开始并在最后一个元素的下一个结束(您也可以在colors = False之后中断,因为一个无效的三元组就足够了):

for i in range(1, len(colorList) - 1):
    if not(colorList[i] == colorList[i-1] or colorList[i] == colorList[i+1]):
        # ... etc

如果您还需要检查第一个和最后一个元素,请使用以下方法:

for i in range(len(colorList)):
    if not((i > 0 and colorList[i] == colorList[i-1]) or (i < len(colorList) - 1 and colorList[i] == colorList[i+1])):
        colors = False
        break

答案 2 :(得分:1)

@MrGeek是完全正确的,@ Sunitha的技术甚至更优雅-我建议您使用他们的一种解决方案,因为它们避免了不必要的逻辑。

但是为什么的答案是“超出范围”是因为您的第二张支票是i < len(colorList),而本应为i < len(colorList) - 1

数组的索引为0,大小为 n 的数组的有效索引范围为 [0 ... n-1]


EDIT:退后一步,发生这些错误是因为您的if条件有点复杂。我建议将其分解为较小的部分-保持循环不变,我会这样写:

def colorChecker(colorList):
    colors = True
    for i in range(len(colorList)):
        prevI = i - 1;
        nextI = i + 1;
        isDifferentFromPrev = prevI < 0 or colorList[i] != colorList[prevI]
        isDifferentFromNext = nextI >= len(colorList) or colorList[i] != colorList[nextI]

        if isDifferentFromPrev and isDifferentFromNext:
            colors = False

    return colors

请注意,我做了一些"not (a or b)" to "not a and not b"替换以简化操作。

阅读上面的代码,您会立即了解正在执行的操作:如果数组中的任何颜色与周围的颜色不同,请将colors设置为False 。 / p>