Lord_Zane 55 Lord_Zane 55 - 2 months ago 31
Python Question

Python iterating over matrix class

from collections.abc import Sequence

class Map(Sequence):
""" Represents a map for a floor as a matrix """

def __init__(self, matrix):
""" Takes a map as a matrix """
self.matrix = matrix
self.height = len(matrix)
self.width = len(matrix[0])
super().__init__()

def __getitem__(self, item):
""" Needed by Sequence """
return self.matrix[item]

def __len__(self):
""" Needed by Sequence """
return len(self.matrix)

def search(self, entity):
""" Returns a generator of tuples that contain the x and y for every element in the map that matches 'entity' """
for row in range(self.height):
for column in range(self.width):
if matrix[row][column] == entity:
yield (row, column)


# Examples

gmap = Map([[0, 0, 0],
[0, 1, 0],
[0, 0, 0]])

for entity in gmap:
print(entity)


How can I implement
__iter__
so that

for entity in gmap:
print(entity)


yields
0 0 0 0 1 0 0 0 0
and not

[0, 0, 0]
[0, 1, 0]
[0, 0, 0]


This would save me from needing to subclass
Sequence
and would make the code for
search()
neater

Additionally, are their any other magic methods I should be using? (aside from
__str__
, im doing that after I get iterating working)

Answer

You may implement __iter__() like so:

from itertools import chain

def __iter__(self):
    return chain.from_iterable(self.matrix)

itertools.chain.from_iterable() takes an iterable of iterables and combines them all together. It creates a generator thus does not use extra memory.