3

関連する質問を見ましたfrozensetが、インナーセットにを使用できません。すべてを変更可能にしたい。

私が理解しているように、PythonはすべてにIDを与えるのに、なぜそれをハッシュとして使用できないのでしょうか。すべての内部セットへの参照のリストは、変更されても維持する必要があります。

編集:わかりました。理由はわかりますが、この場合は、値の平等ではなく、参照の平等のみを考慮しているため、望ましいでしょう。

これどうやってするの?


あなたは「なぜ」と尋ねるつもりなので、私はあなたにいくつかのコードを与えるでしょう:

def remove_captured(self):
    all_chains = set()
    chains = Grid(self.rows, self.cols)
    for m, n, stone in self.enumerate():
        if stone == self[m - 1, n]:
            chains[m, n] = chains[m - 1, n]
            if stone == self[m, n - 1]:
                all_chains.discard(chains[m, n - 1])
                chains[m, n].update(chains[m, n - 1])
                for s in chains[m, n - 1]:
                    chains[s] = chains[m, n]
        elif stone == self[m, n - 1]:
            chains[m, n] = chains[m, n - 1]
        else:
            chains[m, n] = set()
            all_chains.add(chains[m, n])
        chains[m, n].add((m,n))
    chains._print()
    print all_chains

私は基本的にゲームボードを持っているので、ボード上のピースをグループ(または「チェーン」)に分割したいと思います。上記のコードは、追加するまでは正常に機能all_chainsします。すべてのセットが作成されますが、ボード全体を再度繰り返すことなく、作成された各セットにアクセスする方法はありません。

では、作成されたすべてのセットのリストを維持するにはどうすればよいですか?セットも削除する必要があることに注意してください(これが、外部セットに別のセットを使用したい理由です)。


参照をラップするweakref.ref()ことも機能しませんでした:

all_chains.add(weakref.ref(chains[m, n])) # TypeError: unhashable type: 'set'
4

1 に答える 1

1

代わりにセットの辞書を使用することにしました。

def remove_captured(self):
    cdict = {}
    cid = 0
    chains = Grid(self.rows, self.cols)
    for m, n, stone in self.enumerate():
        if stone == self[m - 1, n]:
            chains[m, n] = chains[m - 1, n]
            if stone == self[m, n - 1] and chains[m, n] != chains[m, n - 1]:
                del_id = chains[m, n - 1]
                cdict[chains[m, n]].update(cdict[del_id])
                for c in cdict[del_id]:
                    chains[c] = chains[m, n]
                del cdict[del_id]
        elif stone == self[m, n - 1]:
            chains[m, n] = chains[m, n - 1]
        else:
            cdict[cid] = set()
            chains[m, n] = cid
            cid += 1
        cdict[chains[m, n]].add((m, n))
    chains._print()
    pprint(cdict)

セットを使用する前に常に辞書でセットを検索する必要があるため、それほどきれいではありませんが、機能しているようです.

入力:

0  .  W  W  W  W
1  W  B  B  B  .
2  .  .  .  W  .
3  .  B  B  W  W
4  .  .  B  W  .
   0  1  2  3  4

出力:

0 0 1 1 1 1
1 2 3 3 3 4
2 5 5 5 6 4
3 5 7 7 6 6
4 5 5 7 6 8
  0 1 2 3 4
{0: set([(0, 0)]),
 1: set([(0, 1), (0, 2), (0, 3), (0, 4)]),
 2: set([(1, 0)]),
 3: set([(1, 1), (1, 2), (1, 3)]),
 4: set([(1, 4), (2, 4)]),
 5: set([(2, 0), (2, 1), (2, 2), (3, 0), (4, 0), (4, 1)]),
 6: set([(2, 3), (3, 3), (3, 4), (4, 3)]),
 7: set([(3, 1), (3, 2), (4, 2)]),
 8: set([(4, 4)])}
于 2012-07-14T02:20:00.607 に答える