2016-09-21 90 views
0
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) 

我如何能实现__iter__使Python的迭代矩阵类

for entity in gmap: 
    print(entity) 

产量0 0 0 0 1 0 0 0 0而不是

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

这将节省我从需要继承Sequence并会使代码for search() neater

此外,他们是否还有其他任何我应该使用的魔法方法? (除了__str__,即时通讯做我得到迭代工作之后)

+0

这是一个非常糟糕的主意。这会让你的'__iter__'和'__getitem__'彼此不一致。 – user2357112

+0

此外,它实际上不会使任何搜索器“搜索”。 – user2357112

回答

0

您可以实现__iter__()像这样:

from itertools import chain 

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

itertools.chain.from_iterable()需要iterables的迭代,并将它们结合在一起。它创建一个发生器,因此不会使用额外的内存。

+0

谢谢!我真的试过了,但我只是意识到我搞砸了如何导入它 –

+0

@ Lord_Zane55顺便说一句,矩阵不一定是“行的序列”......返回一行的'__getitem__'相当有趣。这不是很直观。 – Bharel

+0

我发现在线代码片段用于迭代,您能否解释一个矩阵如何不是“行的序列”以及'__getitem__'应该为将来的使用做些什么? –