2017-09-05 10 views
0

私がしようとしているのは、2D配列を持ち、配列内のすべての座標について、1または0を格納している場合は、他の8つの座標を尋ねます。鉱山を探している掃海艇と同様です。Pythonでグリッド座標にどのように追加するのですか?

私はこれ持っていた:

grid = [] 

for fila in range(10): 
    grid.append([]) 
    for columna in range(10): 
     grid[fila].append(0) 

#edited 
for fila in range (10): 
    for columna in range (10): 
     neighbour = 0 
     for i in range 10: 
      for j in range 10: 

       if gird[fila + i][columna + j] == 1 
        neighbour += 1 

をしかし、何かがうまく動作しませんでした。私はまた、エラーをその方法を見つけることを試みるために印刷された文章を持っていましたが、私はまだそれがforループの半分だけを作った理由を理解できませんでした。だから私は、これまでのループのための第二変更:

#edited 
for fila in range (10): 
    for columna in range (10): 
     neighbour = 0 

     if grid[fila - 1][columna - 1] == 1: 
      neighbour += 1 
     if grid[fila - 1][columna] == 1: 
      neighbour += 1 
     if grid[fila - 1][columna + 1] == 1: 
      neighbour += 1 
     if grid[fila][columna - 1] == 1: 
      neighbour += 1 
     if grid[fila][columna + 1] == 1: 
      neighbour += 1 
     if grid[fila + 1][columna - 1] == 1: 
      neighbour += 1 
     if grid[fila + 1][columna] == 1: 
      neighbour += 1 
     if grid[fila + 1][columna + 1] == 1: 
      neighbour += 1 

をし、このエラーを得た:

if grid[fila - 1][columna + 1] == 1: 
IndexError: list index out of range 

私は、グリッド座標に追加することはできませんが、私は引くことができますように思え。何故ですか?

+0

あなたは国境をチェックしますか?例えば最初の行には上位隣がありません。通常、これらの隣接チェックの外側には、さらに '' i> 0'''と '' i sascha

+0

まず、そのような規則的な配列を作成したい場合は、間違いなく 'numpy'に切り替える必要があります。最初の二重ループは 'grid = numpy.zeros((10,10))'という単一の行になります。つまり、私は実際にあなたのコードのロジックに従っているわけではありません。まず 'filea'と' columna'をループインデックスとして使用し、後で配列インデックスのオフセットとして使用します。これはあなたが本当に望んでいるとは思いません。 'filea'と' columna'から1を引くことができる理由は、初期ループの後では両方とも '9 'に等しく、' 9 + 1 = 10'は範囲外です。 –

+0

omg sry私は質問の中で何かを書くのを忘れていました。編集してより意味をなさくするでしょう。 –

答えて

-1

エラーは、それはあなたが座標がグリッド内に収まるかどうかを確認する必要がある、と言うまさにです:

0 <= i < 10 and 0 <= j < 10 
それ以外の

あなたは、メモリ内に存在しない要素にアクセスしようとしていますかあなたが実際に考えている要素ではない要素です - Pythonは負のインデックスを処理しますが、最後から数えられます。

など。 a[-1]は最後の要素で、まったく同じa[len(a) - 1]と同じです。

0

有効なインデックスは、-len(grid)からlen(grid)-1です。正のインデックスは、正面からオフセットしたアクセス要素、背面からの負の要素です。インデックスがlen(grid)-1より大きい場合、追加すると範囲エラーが表示されます。減算は、-len(grid)より小さいインデックス値を取得しない限り、範囲エラーを与えません。あなたは0(ゼロ)である下限をチェックしませんが、小さな負のインデックスが後端から値を返すので、あなたのために働くようです。これは間違った近隣結果につながる静かなエラーです。

+0

私は配列の境界でのみエラーがあっても意味がありますが、最初のforループでは、座標は、左上、上隅、および左上のコーナーの近傍座標のみを表示します。それはどこにでもエラーをドラッグしますか? –

+0

エラーを示す完全なコードを投稿してください。 – stefan

0

オフセットを計算する場合は、オフセットがリストの範囲内にあることを確認する必要があります。したがって、要素が10個ある場合は、11番目の要素にアクセスしないでください。

import collections 

grid_offset = collections.namedtuple('grid_offset', 'dr dc') 

Grid = [[0 for c in range(10)] for r in range(10)] 
Grid_height = len(Grid) 
Grid_width = len(Grid[0]) 

Neighbors = [ 
     grid_offset(dr, dc) 
      for dr in range(-1, 2) 
      for dc in range(-1, 2) 
      if not dr == dc == 0 
    ] 

def count_neighbors(row, col): 
    count = 0 
    for nb in Neighbors: 
     r = row + nb.dr 
     c = col + nb.dc 
     if 0 <= r < Grid_height and 0 <= c < Grid_width: 
      # Add the value, or just add one? 
      count += Grid[r][c] 

    return count 


Grid[4][6] = 1 
Grid[5][4] = 1 
Grid[5][5] = 1 

for row in range(10): 
    for col in range(10): 
     print(count_neighbors(row, col), "", end='') 

    print() 

プリント:

$ python test.py 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 1 1 1 0 0 
0 0 0 1 2 3 1 1 0 0 
0 0 0 1 1 2 2 1 0 0 
0 0 0 1 2 2 1 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
+0

Sryですが、私はかなり初心者です。コレクションの使い方はわかりません。どうやって使うのか、 'grid_offset'は何をしているのか説明できますか? –

+0

'grid_offset'は[' collections.namedtuple'](https://docs.python.org/3/library/collections.html#collections.namedtuple)です。名前付きタプルは、t [0]、t [1]の代わりに名前のついたフィールドを持つ単純なタプル型です。これにより、コードを読みやすくなります。 'Neighbors'は、セルの8つの可能な近傍を定義する(-1、0)または(0,1)のような' grid_offset'タプルの集合です。 –

+0

ありがとうございました。グリッド自体に何も追加したくないのですが、それに基づいて値を1または0に変更するだけです –

関連する問題