0

Let's say I have a two dimensional grid of 10x10 cells. The top left cell has coordinates (0,0) and the bottom right cell has coordinates (9,9).

The code below doesn't seem to function the way I want it to. I can't figure out what I am doing wrong.

'''

X = 10
Y = 10

class Cell:
  def __init__(self,x,y) -> None:
      self.coordinates = (x,y)
      self.neigbors = self.find_neighbors()

  def find_neighbors(self):
    x,y = self.coordinates

    neighbors = [
      (x+1,y),(x-1,y),(x,y+1),(x,y-1),(x+1,y+1),
      (x+1,y-1),(x-1,y+1),(x-1,y-1)
    ]

    for neighbor in neighbors:
      if neighbor[0] < 0 or neighbor[1] < 0:
       neighbors.remove(neighbor)
      elif neighbor[0] >= X or neighbor[1] >= Y:
        neighbors.remove(neighbor)

    return neighbors

cell1 = Cell(0,0)
cell1.neigbors
# [(1, 0), (0, 1), (1, 1), (-1, 1)]
# shouldn't have (-1,1)

cell2 = Cell(9,9)
cell2.neigbors
# [(8, 9), (9, 8), (10, 8), (8, 8)]
# shouldn't have (10,8)

'''

Sanawar
  • 9
  • 5
  • 1
    Does this answer your question? [Strange result when removing item from a list while iterating over it](https://stackoverflow.com/questions/6260089/strange-result-when-removing-item-from-a-list-while-iterating-over-it) – Passerby Nov 22 '21 at 11:11
  • 1
    Does this answer your question? [How to remove items from a list while iterating?](https://stackoverflow.com/questions/1207406/how-to-remove-items-from-a-list-while-iterating) – GPhilo Nov 22 '21 at 11:11
  • @Passerby Thank you. I fixed it by appending the unwanted neighbors to a separate list and them removing them. – Sanawar Nov 22 '21 at 11:19

2 Answers2

1

Better not to remove items from a list while iterating over it (as already pointed out in the comments). Here's an idea where you mark the entries in the list of potential coordinates as "unwanted" then subsequently reconstruct the desired output:

MX = 10
MY = 10


def neighbours(x, y):
    pn = [(x-1, y), (x+1, y), (x-1, y-1), (x, y-1),
          (x+1, y-1), (x-1, y+1), (x, y+1), (x+1, y+1)]
    for i, t in enumerate(pn):
        if t[0] < 0 or t[1] < 0 or t[0] >= MX or t[1] >= MY:
            pn[i] = None
    return [c for c in pn if c is not None]


print(neighbours(5, 4))
0

Instead of the for-loop put this piece.

neighbors = [neighbor for neighbor in neighbors if validate_cell(neighbor)]

The function validate_cell(coordinate).

validate_cell(coordinate):
    if coordinate[0] < 0 or coordinate[1] < 0:
        return False
    elif coordinate[0] >= X or coordinate[1] >= Y:
        return False
    else:
        return True
Ian Pringle
  • 323
  • 1
  • 5
  • 19
Abdur Rakib
  • 336
  • 1
  • 12