2016-09-21 3 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) 

がどのように私はそれがは、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をサブクラス化する必要から私を救う__iter__を実装することができます行列クラスを反復処理し、コードになるだろうsearch() neater

さらに、私が使用しなければならない他の魔法の方法もありますか?あなたがそうのような__iter__()を実装することができる

+0

これは本当に悪い考えです。あなたの '__iter__'と' __getitem__'はお互いに矛盾しています。 – user2357112

+0

また、それは実際には何の検索もしません。 – user2357112

答えて

0

を(私は作業を反復取得した後はさておき__str__から、イムはそれをやって):

from itertools import chain 

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

itertools.chain.from_iterable()は、反復可能オブジェクトの反復可能になりますし、それらすべてを兼ね備えています。それはジェネレータを作成し、余分なメモリを使用しません。

+0

ありがとう!私は実際にこれを試しましたが、私はちょうど私がそれをインポートする方法を混乱させたことを理解しました –

+0

@ Lord_Zane55 btw、行列は必ずしも "行のシーケンス"ではありません...行を返す '__getitem__'は面白いです。これはあまり直感的ではありません。 – Bharel

+0

私は繰り返しのためにスニペットを見つけました。行列が「行の列」ではなく、将来の使用のためにはどのような '__getitem__'が必要なのか説明できますか? –