我遇到了一個問題,可以正確地散列我的對象。請看下面的代碼:重寫後相同的散列值但不相同的對象__hash__
class Foo:
def __init__(self, bar):
self.keys = list(bar.keys())
self.values = list(bar.values())
def __str__(self):
return ', '.join('%s: %s' % z for z in zip(self.keys, self.values))
def __hash__(self):
return hash(str(self))
if __name__ == '__main__':
result = set()
d = { 1: 2, 3: 4, 5: 6, 7: 8 }
for i in range(10):
result.add(Foo(d))
for r in result:
print r, hash(r)
我希望得到的結果設置爲包含一個單一的元素,因爲所有增加Foo
對象具有相同的內容,因此,相同的哈希。
然而,這是結果:
[email protected]:~/Desktop/stackoverflow$ python hashproblem.py
1: 2, 3: 4, 5: 6, 7: 8 2131119371379196338
1: 2, 3: 4, 5: 6, 7: 8 2131119371379196338
1: 2, 3: 4, 5: 6, 7: 8 2131119371379196338
1: 2, 3: 4, 5: 6, 7: 8 2131119371379196338
1: 2, 3: 4, 5: 6, 7: 8 2131119371379196338
1: 2, 3: 4, 5: 6, 7: 8 2131119371379196338
1: 2, 3: 4, 5: 6, 7: 8 2131119371379196338
1: 2, 3: 4, 5: 6, 7: 8 2131119371379196338
1: 2, 3: 4, 5: 6, 7: 8 2131119371379196338
1: 2, 3: 4, 5: 6, 7: 8 2131119371379196338
有什麼問題嗎?散列做的看起來一樣,所以不應該被內置的set
對象視爲重複對象嗎?爲什麼該集合包含重複項?
我注意到,如果在向該集合添加元素時使用str(Foo(d))
而不是Foo(d)
,那麼事情就會按預期工作。爲什麼這有關係?
Python版本是:
[email protected]:~/Desktop/stackoverflow$ python --version
Python 2.6.6
謝謝!這似乎工作。我是否需要重寫`__hash__`,或者`__eq__`是否足夠? – misha 2011-02-14 02:42:05