JustOscarJ
JustOscarJ

Reputation: 89

How do you find the neighbours of an item in a 2D list?

[
[a,b,c,d],
[e,f,g,h],
[i,j,k,l]
]

For example. g is touching b,c,d,f,h,j,k,l and a is touching e,f,b. I tried a method where I made it a big list and did some trash, but it fell apart, tbh. Here's the code if interested:

import math

big_list = []
x= [
["a", "b", "c", "d", "e", "f"],
["g", "h", "i", "j", "k", "l"],
["m", "n", "o", "p", "q", "r"],
["s", "t", "u", "v", "w", "x"],
["y", "z", "1", "2", "3", "4"]
]

#def find_neighbours(num):
for y in x:
    for element in y:
        big_list.append(element)

def find_row(element):
    columns = len(x)
    loc = big_list.index(element)
    exact_row = (loc)/columns
    return(math.floor(exact_row))

def find_column(element):
    row = find_row(element)
    exact_column = x[row]
    return(exact_column)

print(find_column("x"))

The list can be any size and is not always going to be a square.

Upvotes: 1

Views: 982

Answers (3)

RK Replogle
RK Replogle

Reputation: 151

# How do you find the neighbours of an item in a 2D list?

import numpy as np


def neighbors(array, item):
    item_loc = tuple(np.asarray(np.where(array == item)).T[0].tolist())
    s = tuple(np.array(array.shape) - 1)
    n = np.array([-1, 0, +1])
    rows = item_loc[0] + n
    cols = item_loc[1] + n
    neighbor_loc = [
        (x, y) for x in rows for y in cols if (0 <= x <= s[0]) & (0 <= y <= s[1])
    ]
    neighbor_loc.remove(item_loc)
    print(
        f"The neighbors of {item} are {array[tuple(np.transpose(neighbor_loc))].tolist()}."
    )


array = np.array(
    [
        ["a", "b", "c", "d", "e", "f"],
        ["g", "h", "i", "j", "k", "l"],
        ["m", "n", "o", "p", "q", "r"],
        ["s", "t", "u", "v", "w", "x"],
        ["y", "z", "1", "2", "3", "4"],
    ]
)
item = "r"
neighbors(array, item)

First find the location of the item. Use the shape to determine the edges of the array. Determine the rows and columns that have neighbors, but remove any locations that do not exist. Then remove the items location. Finally, retrieve the neighbors.

This code assumes that all items in the array are unique, and that the item being requested exists in the array.

Upvotes: 1

martineau
martineau

Reputation: 123423

There are basically two steps involved:

  1. Find the indices of the target item (if any).
  2. Determine the indices of the items around it that are valid.

Here's a literal implementation:

m = [['a', 'b', 'c', 'd', 'e', 'f'],
     ['g', 'h', 'i', 'j', 'k', 'l'],
     ['m', 'n', 'o', 'p', 'q', 'r'],
     ['s', 't', 'u', 'v', 'w', 'x'],
     ['y', 'z', '1', '2', '3', '4']]

width = len(m[0])
height = len(m)

target = 'a'
x = None
for y in range(height):
    try:
        x = m[y].index(target)
    except ValueError:
        continue
    else:
        break  # Found

if x is not None:
    print(f'Target {target!r} found in position [{x}, {y}]')
else:
    raise RuntimeError(f'Target {target!r} not found.')

neighbours = []
for j in range(y-1, y+2):
    if -1 < j < height:
        for i in range(x-1, x+2):
            if -1 < i < width and (i, j) != (x, y):
                neighbours.append((i, j))

print('neighbours:', neighbours)

Upvotes: 0

BrokenBenchmark
BrokenBenchmark

Reputation: 19223

Find the row and column index of the element. Then, you can define a list of row / column differences to check in order to generate the indices of the neighbors. Finally, you can loop through these differences to find the neighbors.

from itertools import product

board = [
    ['a','b','c','d'],
    ['e','f','g','h'],
    ['i','j','k','l']
]

target = 'a'

DELTAS = [x for x in product((-1, 0, 1), repeat=2) if x != (0, 0)]

for row_idx in range(len(board)):
    for col_idx in range(len(board[0])):
        if board[row_idx][col_idx] == target:
            row = row_idx
            col = col_idx
            break

neighbors = []
for row_delta, col_delta in DELTAS:
    if 0 <= row + row_delta < len(board) and 0 <= col + col_delta < len(board[0]):
        neighbors.append(board[row + row_delta][col + col_delta])

print(neighbors)

This outputs:

['b', 'e', 'f']

Upvotes: 0

Related Questions