2016-12-21 17 views
-1

オブジェクトを含むセットがあるとします。Pythonでオブジェクトへの参照を取得する方法

class C(object): 
    def __init__(self, value): 
     self.value = value 
    def __repr__(self): 
     return 'C({}):{}'.format(self.value, id(self)) 
    def __eq__(self, other): 
     return self.value == other.value 
    def __hash__(self): 
     return hash(self.value) 

cset = {C(1), C(2)} 
print 'cset:', cset 

cset: set([C(1):140241436167120, C(2):140241436167184]) 

私はセット内のオブジェクトを見つけて、そのオブジェクトへの参照を取得します。

c1 = C(1) 
print 'c1:', c1 

found, = cset & {c1} 
print 'way1 found:', found 
found, = {c1} & cset 
print 'way2 found:', found 

c1: C(1):140241436167248 
way1 found: C(1):140241436167248 
way2 found: C(1):140241436167248 

これらの方法は問題ありません。セット内のオブジェクト(id = 140241436167120)ではなく、c1(id = 140241436167248)への参照を返します。

ちょうど私が欲しいものを表示するために、迅速かつ汚れた方法はこれのようなものです。

found, = [x for x in cset if x == c1] 
print 'way3 found:', found 

way3 found: C(1):140241436167120 

この方法では、私が望むもの、つまりセット内のオブジェクト(ID = 140241436167120)への参照を返します。 しかし、それは線形検索を使用しています。もっと良い方法はありますか?

+0

'x == c1'を実行したときに、' set'に参照 'c1'がすでにあります。あなたがするのは、 'set'から' c1'への同じ参照を取ることだけです。なぜあなたはそれをしたいのですか? –

+0

'c1' *はセット内のオブジェクトです。私は本当にあなたが何を求めているのか分からない。 –

+1

"参照を返す"とはどういう意味ですか? * Everything *はPythonのオブジェクトへの参照です。 –

答えて

2

問題は、setをマッピングのように使用しようとしていることです。それはうまく動作しません...

代わりに、あなたのオブジェクトを明示的にハッシュ化しないでください。一意制約がある場合は、ディクショナリを使用して値をセットではなくインスタンスにマップします。辞書はsetと同じくらい簡単に一意性を強制することができ、必要なマッピング動作を提供します。

if c1.value in cdict: 
    c1 = cdict[c1.value] # Trade in the `c1` we have for one already in `cdict` 

また、dictを使用すると、ほとんどの場合、読みやすさの観点から勝利している以下「賢い」です。

関連する問題