1

Python 2D 配列を反復処理し、各アイテムとその周囲のすべてのアイテムを MxN 近傍に生成するイテレータを生成する必要があります。

たとえば、チェッカーボード パターンの 0 と 1 のリストがある場合、次のような 3x3 近傍を生成するイテレータ オブジェクトが必要です。

[0,1,0],
[1,0,1],
[0,1,0]

注意: 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]
4

2 に答える 2

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 の場合と基本的に同じです。

于 2013-06-24T08:01:40.937 に答える
0

多くの場合、要素を 1 次元リストに格納し、配列の論理幅と高さに基づいてオフセット ベースを計算することで、2 次元配列にすばやくアクセスできます。多くの場合、内部で 1 つの次元を処理するだけでよい計算と境界チェックを簡素化できます。

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]
于 2013-06-24T11:01:24.770 に答える