1

我有一个看起来像这样的while循环:

while a[xp][yp] - a[xp-1][yp] == 0  and a[xp][yp] - a[xp+1][yp] == 0 and a[xp][yp] - a[xp][yp-1] == 0 and a[xp][yp] - a[xp][yp+1] == 0:
    c=randint(0,3)
    if c==0:
        xp=xp+1; yp=yp
    elif c==1:
        xp=xp-1; yp=yp
    elif c==2:
        xp=xp; yp=yp+1
    else:
        xp=xp; yp=yp-1
    xp=xp; yp=yp

问题是,如果 xp 或 yp = 0 或 n(数组在 x 方向或 y 上的长度,它是一个方阵),那么 while 循环中的条件就会失效,我会得到一个越界错误。如果 xp=0 或 xp=n 或 yp=0 或 yp=n (我有一段单独的代码可以做到这一点),我只想获得一组新的坐标,然后让 while 循环再次运行。

代码的性质似乎是每 4 次代码中约有 1 次运行而不会超出范围。我只需要它继续运行,直到它发生工作。

4

1 回答 1

1

您可以简单地检查该操作是否会将索引推出越界,如下所示:

if c==0 and xp < len(a)-1:
  xp += 1
elif c==1 and xp > 0:
  xp -= 1
# etc...

这将确保在实际更改之前xp保持在界限内,而不是事后查看。


第二个问题在您的while声明中 - 即使您确保xp并且yp在数组的范围内,您也可以在初始条件下检查外部:

while a[xp][yp] - a[xp-1][yp] == 0 and a[xp][yp] - a[xp+1][yp] == 0  \ 
  and a[xp][yp] - a[xp][yp-1] == 0 and a[xp][yp] - a[xp][yp+1] == 0:

在这里,我假设它a的大小为 10 x 10(索引从 0 到 9)。如果我们设置xp为 0 和yp9,那么这将是:

while a[0][9] - a[-1][9] == 0 and a[0][9] - a[1][9] == 0 \
      a[0][9] - a[0][10] == 0 and a[0][9] - a[0][10]:

a[10]将抛出越界错误,因此您必须确定当索引位于数组边界上时如何更改循环。请注意,a[9]它仍然是数组的有效索引 - 它正在检查下一个存在问题的索引。

顺便说一句,实际上a[-1] 不会引发异常,尽管这对您来说可能是一个逻辑错误 -负索引将访问数组中的最后一个元素


修复它的一种可能方法,尽管它取决于您需要做什么:Python 会使operator短路or,因此可以编写类似这样的内容而不会引发异常:

while (xp <= len(a)-2 or a[xp][yp]-a[xp+1][yp] == 0) and \
      (xp > 1         or a[xp][yp]-a[xp-1][yp] == 0) and #etc...

这里,如果小于xplen(a)-2一个子句求值为真),则语句的另一半or不会被求值,越界异常也不会发生,循环会继续运行(只要xp也是大于 1,并且语句的其余部分也计算为真)。

于 2013-02-20T17:06:09.447 回答