在python中处理2D列表边界检查的最佳方法?

在python中处理2D列表边界检查的最佳方法?,python,python-3.x,Python,Python 3.x,我有一个2D列表,如下所示,如果单元格周围的单元格为0,我想将单元格值从1更改为0 像 我想我可以使用8 if/else逻辑进行检查,但不知道是否有更好或干净的方法来进行检查?我将使用python生成器获取有效的邻居,并使用all检查所有邻居是否为零 def更新单元(网格): 如果不是网格或不是网格[0]: 返回 m、 n=len(网格),len(网格[0]) def有效(i,j): 返回0我将使用python生成器获取有效的邻居,并使用all检查所有邻居是否为零 def更新单元(网格): 如果

我有一个2D列表,如下所示,如果单元格周围的单元格为0,我想将单元格值从1更改为0 像


我想我可以使用8 if/else逻辑进行检查,但不知道是否有更好或干净的方法来进行检查?

我将使用python生成器获取有效的邻居,并使用
all
检查所有邻居是否为零

def更新单元(网格):
如果不是网格或不是网格[0]:
返回
m、 n=len(网格),len(网格[0])
def有效(i,j):

返回0我将使用python生成器获取有效的邻居,并使用
all
检查所有邻居是否为零

def更新单元(网格):
如果不是网格或不是网格[0]:
返回
m、 n=len(网格),len(网格[0])
def有效(i,j):

返回0对所讨论点周围的3x3列表求和。如果总和为
1
(中心单元格的值),则将其设置为
0

要选择3x3段,您可以

  • 在所需的3x3切片上迭代
  • 使用切片为每个检查创建一个新的3x3段
  • 将列表转换为NumPy 2D数组;NumPy具有很好的切片功能

围绕问题点汇总3x3列表。如果总和为
1
(中心单元格的值),则将其设置为
0

要选择3x3段,您可以

  • 在所需的3x3切片上迭代
  • 使用切片为每个检查创建一个新的3x3段
  • 将列表转换为NumPy 2D数组;NumPy具有很好的切片功能

我会写if,但是像另一个答案那样生成邻居是很优雅的

如果您可以更改数据结构并需要速度,则可以使用重影单元

用如下所示的零环绕网格:

       0 0 0 0
1 2    0 1 2 0
4 5    0 4 5 0
       0 0 0 0

然后你可以从1..n-1迭代,并且总是有所有的邻居

我会写if,但是像另一个答案那样生成邻居是很优雅的

如果您可以更改数据结构并需要速度,则可以使用重影单元

用如下所示的零环绕网格:

       0 0 0 0
1 2    0 1 2 0
4 5    0 4 5 0
       0 0 0 0
然后您可以从1..n-1进行迭代,并始终拥有所有邻居,一种方法是:

def neighbors(m,r,c):
    return sum((
        sum(m[r-1][max(0,c-1):c+2]) if 0 <= r-1 < len(m) else 0,
        sum(m[r  ][max(0,c-1):c+2]) if 0 <= r   < len(m) else 0,
        sum(m[r+1][max(0,c-1):c+2]) if 0 <= r+1 < len(m) else 0,
    )) - m[r][c]
这里唯一真正有点聪明的事情是,通过使用切片,您可以对越界错误进行排序。因此
x=[1,2,3];打印(x[100:200])
只打印一个空列表,没有
索引器

我认为您应该使用此代码而不是简单的嵌套for循环吗?几乎肯定不会。一种方法是:

def neighbors(m,r,c):
    return sum((
        sum(m[r-1][max(0,c-1):c+2]) if 0 <= r-1 < len(m) else 0,
        sum(m[r  ][max(0,c-1):c+2]) if 0 <= r   < len(m) else 0,
        sum(m[r+1][max(0,c-1):c+2]) if 0 <= r+1 < len(m) else 0,
    )) - m[r][c]
这里唯一真正有点聪明的事情是,通过使用切片,您可以对越界错误进行排序。因此
x=[1,2,3];打印(x[100:200])
只打印一个空列表,没有
索引器

我认为您应该使用此代码而不是简单的嵌套for循环吗?几乎肯定不是