1

Cellオブジェクトをセットに格納して(クラスを使用する必要があります)単純なライフゲームを作成しようとしていますが、セルオブジェクトはハッシュできないためセットに追加できないという問題に到達しました...何かありますかこれを回避する方法は?ありがとう!

class Cell():
    def __init__(self, row, col):
        self.row = row
        self.col = col
    def getRow(self):
        return self.row
    def getCol(self):
        return self.col
    def __eq__(self, other):
        if isinstance(other, self.__class__):
            return self.__dict__ == other.__dict__
        else:
            return False

    def __ne__(self, other):
        return not self.__eq__(other)    

class SparseLifeGrid(set):
    # Creates a new infinite-sized game grid with all cells set to dead.
    def __init__(self):
        self.rowList = []
        self.colList = []
        self.cellSet = set()

    def __add__(self, cell):
        self.cellSet.add(cell)
        self.rowList.append(cell.getRow())     
        self.colList.append(cell.getCol())     

    def minRange(self):
        #Returns a 2-tuple (minrow, mincol) that contains the minimum
        #row index and the minimum
        #column index that is currently occupied by a live cell.
        #None is returned if there are no alive cells.        
        return (sorted(self.rowList)[0], sorted(self.rowList)[0])

    def maxRange(self):
        #Returns a 2-tuple (maxrow, maxcol) that contains the
        #maximum row index and the maximum
        #column index that is currently occupied by a live cell.
        #None is returned if there are no live cells.        
        return (sorted(self.rowList,reverse = True)[0],\
                sorted(self.colList,reverse = True)[0])

    def clearCell(self, row, col):
        #Clears the individual cell (row, col) and sets it to dead.
        #If the cell is already dead, no action is taken.
        for item in self:
            if item == Cell(row,col):
                self.remove(item)

    def setCell(self, row, col):
        #Sets the indicated cell (row, col) to be alive.
        #If the cell is already alive, no action is taken.
        self.__add__(Cell(row,col))

    def isLiveCell(self, row, col):
        #Returns a boolean value indicating if the given
        #cell (row, col) contains a live organism.
        return Cell(row,col) in self

    def numLiveNeighbors(self, row, col):
    #checks how many live adjacents (not diagonals I think) a cell has
        surround = 0
        if self.isLiveCell(row+1,col):
            surround += 1
        if self.isLiveCell(row-1,col):
            surround += 1
        if self.isLiveCell(row, col+1):
            surround += 1
        if self.isLiveCell(row, col-1):
            surround += 1
        return surround

G = SparseLifeGrid()
G.setCell(2,3)
4

2 に答える 2

0

__hash__Cellインスタンスを不変にしてから、常に同じままのメソッドを作成する必要があります。タプルを直接使用できない場合は、次の方法があります(から少しだけ借用しますtuple)。

class Cell:
    # each cell will have exactly two values, so no need for __dict__
    __slots__ = ["row", "col"]

    # set up values at construction time using super().__setitem__()
    def __init__(self, row, col):
        super().__setitem__("row", row)
        super().__setitem__("col", col)
        return self

    # a Cell is intended to be immutable, so __setattr__ always raises an error
    def __setattr__(self, name, value):
        if hasattr(self, name):
            raise AttributeError("{!r} object attribute {!r} is read-only"
                                 .format(self.__class__.__name__, name))
        else:
            raise AttributeError("{!r} object has no attribute {!r}"
                                 .format(self.__class__.__name__, name))

    # comparison operators
    def __eq__(self, other):
        return (isinstance(other, Cell) and
                self.row == other.row and
                self.col == other.col)

    def __ne__(self, other):
        return not self == other

    # hash function, with a value borrowed from a tuple
    def __hash__(self):
        return hash((self.row, self.col))

ただし、これはかなり多くの作業ですが、次のようなものに相当します。

Cell = collections.namedtuple(["row", "col"])

グリッドクラスにもいくつかの問題があります。たとえば__add__、加算演算子の実装に使用されるをオーバーライドしていますが、何も返さないため、期待どおりに機能しません。add代わりに、メソッドを(アンダースコアなしで)オーバーライドすることを意味しているのではないかと思います。ただし、その場合、super().add()グリッドを実際にセットとして機能させるには、適切な引数を指定して呼び出す必要があります。

また、(O(N log N)ではなくO(N))よりmin(lst)もはるかに高速である必要があります。sorted(lst)[0]

于 2012-10-26T13:59:23.623 に答える
0

あなたのオブジェクトは変更可能で、実装していません__hash__()。とにかく、あなたは本当にそれをしたくありません。セルは、存在する場合に生きていることを示すためだけに存在するため(row, col) 、セットでタプルを使用するだけです。タプルは不変かつハッシュ可能であるため、それらをセットに入れることができます。

セルではなく、グリッドとゲームのクラスとオブジェクトを使用します。

于 2012-10-25T22:32:09.690 に答える