Determining neighbours of cell two dimensional list

Viewed 45813

I have a list of lists, something like

[[1, 2, 3,],[4, 5, 6,],[7, 8, 9]].

Represented graphically as:

1 2 3
4 5 6
7 8 9

I'm looking for an elegant approach to check the value of neighbours of a cell, horizontally, vertically and diagonally. For instance, the neighbours of [0][2] are [0][1], [1][1] and [1][2] or the numbers 2, 5, 6.

Now I realise, I could just do a bruteforce attack checking every value a la:

[i-1][j]
[i][j-1]
[i-1][j-1]
[i+1][j]
[i][j+1]
[i+1][j+1]
[i+1][j-1]
[i-1][j+1]

But thats easy, and I figured I can learn more by seeing some more elegant approaches.

15 Answers

If lambdas daunt you here you are .But lambdas make your code look clean.@johniek_comp has a very clean solution TBH

k,l=(2,3)
x = (0,-1,+1)
y = (0,-1,+1)
cell_u = ((k+a,l+b) for a in x for b in y)
print(list(cell_u))

Inspired by one of the previous answers.

You can use min() and max() functions to shorten the calculations:

width = 3
height = 3

[(x2, y2) for x2 in range(max(0, x-1), min(width, x+2)) 
                    for y2 in range(max(0, y-1), min(height, y+2))
                    if (x2, y2) != (x, y)]

Inspired by johniek's answer here is my solution which also checks for boundaries.

def get_neighbours(node, grid_map):
   row_index, col_index = node
   height, width = len(grid_map), len(grid_map[0])
   cells = list(starmap(lambda a, b: (row_index + a, col_index + b), product((0, -1, +1), (0, -1, +1))))
   cells.pop(0) #  do not include original node
   cells = list(filter(lambda cell: cell[0] in range(height) and cell[1] in range(width), cells))
   return cells
def numCells(grid):
    x=len(grid)
    y=len(grid[0])
    c=0
    for i in range(x):
        for j in range(y):
            value_=grid[i][j]
            f=1
            for i2 in range(max(0,i-1),min(x,i+2)):
                for j2 in range(max(0,j-1),min(y,j+2)):
                    if (i2,j2) != (i,j) and value_<=grid[i2][j2]:
                        flag=0
                        break
                if flag ==0:
                    break
                else:
                    c+=1
    return c
Related