Это работает с массивами numpy
def get_adjacent_cells(arr, selected_idxs):
"""
>>> arr = np.ones((3,))
>>> get_adjacent_cells(arr, {(1,)})
{(0,), (1,), (2,)}
>>> arr = np.ones((3,2))
>>> get_adjacent_cells(arr, {(1,1)})
{(0, 1), (1, 0), (1, 1), (2, 1)}
>>> arr = np.ones((3,2,3))
>>> {(0, 1, 0), (1, 0, 0), (1, 1, 0), (1, 1, 1), (2, 1, 0)}
>>> arr = np.ones((3,2,3))
>>> get_adjacent_cells(arr, {(1,1,0), (0,1,0)})
{(0, 0, 0), (0, 1, 0), (0, 1, 1), (1, 0, 0), (1, 1, 0), (1, 1, 1), (2, 1, 0)}
"""
w = np.asarray(list(selected_idxs))
new_idxs = []
for col in range(w.shape[1]):
w_ = w.copy()
w_[:,col] += 1
new_idxs.extend(list(w_))
w_ = w.copy()
w_[:,col] -= 1
new_idxs.extend(list(w_))
new_idxs = np.array(new_idxs)
# remove out of bounds coordinates
for col, dim_size in enumerate(arr.shape):
new_idxs = new_idxs[(new_idxs[:, col] >= 0) & (new_idxs[:, col] < dim_size)]
return selected_idxs.union(map(tuple, new_idxs))