2016-09-21 114 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__'應該爲將來的使用做些什麼? –