我需要生成一个迭代器,它将迭代Python 2D数组,并在MxN邻域中生成每个项目及其周围的所有项目。
例如,给定一个棋盘图案中的0和1的列表,我需要一个迭代器对象,它将产生一个3x3的邻域,例如:
[0,1,0],
[1,0,1],
[0,1,0]
N.B。 yield不需要是另一个数组,但是能够引用具有相对于中心项的位置/索引的邻居,或者至少相对于彼此是很好的。
提前致谢。
编辑:到目前为止,我一直试图仅通过索引来做,即
for x in range(len(S)):
for y in range(len(S[0])):
for i in range(-1,2):
for j in range(-1,2):
#access neighbour with S[x+i][y+j]
答案 0 :(得分:0)
board = [
[1,0,1,0,1],
[1,0,1,0,1],
[1,0,1,0,1],
[1,0,1,0,1],
[1,0,1,0,1]
]
def clamp(minV,maxV,x):
if x < minV:
return minV
elif x > maxV:
return maxV
else:
return x
def getNeighbour(grid,startx,starty,radius):
width = len(grid[starty])
height = len(grid)
neighbourhood = []
for y in range(clamp(0,height,starty-radius),clamp(0,height,starty+radius)+1):
row = []
for x in range(clamp(0,width,startx-radius),clamp(0,width,startx+radius)+1):
if x != startx or (x==startx and y != starty):
row.append(grid[y][x])
neighbourhood.append(row)
return neighbourhood
示例:
>>> pprint(getNeighbour(board, 0, 0, 1))
[0]
[1, 0] (expected)
>>> pprint(getNeighbour(board, 2, 2, 1))
[0, 1, 0]
[0, 0]
[0, 1, 0] (expected)
>>>
使用如下列表来解决性能方面:
board = [[1,0]*2000]*1000
运行时间与电路板10x10
基本相同答案 1 :(得分:0)
通常可以通过将元素存储在一维列表中并根据数组的逻辑宽度和高度计算偏移量来快速访问二维数组。它通常可以简化计算和边界检查,只需要在内部处理一个维度。
class Board(object):
def __init__(self, width, height):
self.height = height
self.width = width
self.size = width*height
self.board = [i%2 for i in xrange(self.size)] # checkerboard init
def __getitem__(coords):
""" get board[x, y] """
offset = coords[1]*self.width + coords[0]
return self.board[offset]
def __setitem__(coords, value):
""" set board[x, y] = value """
offset = coords[1]*self.width + coords[0]
self.board[offset] = value
def __str__(self):
lines = []
for y in xrange(self.height):
offset = y*self.width
row = self.board[offset:offset+self.width]
lines.append(','.join(str(v) for v in row))
return ',\n'.join(lines)
def neighbourhood(self, x, y):
position = y*self.width + x
for offset in [
position-self.width-1, position-self.width, position-self.width+1,
position-1, position+1,
position+self.width-1, position+self.width, position+self.width+1]:
if -1 < offset < self.size:
yield self.board[offset]
board = Board(5, 5)
print board
print
print [value for value in board.neighbourhood(0, 0)]
print [value for value in board.neighbourhood(2, 2)]
输出:
0,1,0,1,0,
1,0,1,0,1,
0,1,0,1,0,
1,0,1,0,1,
0,1,0,1,0
[1, 0, 1, 0]
[0, 1, 0, 1, 1, 0, 1, 0]