蟒蛇。在一组对象中的身份。并散列 [英] Python. Identity in sets of objects. And hashing

查看:133
本文介绍了蟒蛇。在一组对象中的身份。并散列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

__hash__和__eq__如何在集合中进行识别?
例如一些代码应该有助于解决一些多米诺骨牌难题:

$ p $ class foo(object):
def __init __(self,one,two):
self.one = one
self.two = two
def __eq __(self,other):
if(self.one == other.one)和(self.two == other.two):return True
if(self.two == other.one)and(self.one == other.two):return True
返回False
def __hash __(self):
返回hash(self.one + self.two)
$ bs = set()

对于范围(7)中的i:
在范围(7)中为j:
s.add(foo(i,j))
len(s)//返回28为什么?

如果我只使用__eq __()len(s)等于49.它可以,因为我理解对象(例如1-2和2-1)不一样,但表示相同的多米诺骨牌。所以我添加了散列函数。
现在它按照我想要的方式工作,但我不明白一件事:1-3和2-2的散列应该相同,因此它们应该被计算为相同的对象,并且不应该添加到设置。但他们做到了! Im stuck。

解决方案

字典/设置目的的平等取决于 __ eq __ 。但是,要求比较相等的对象具有相同的散列值,这就是为什么您需要 __ hash __ 。有关类似问题,请参阅此问题讨论。

散列本身不能确定两个对象在字典中是否相同。散列就像一个快捷方式,只有一种方式:如果两个对象具有不同的散列,那么它们肯定不是相等的;但是如果它们具有相同的散列值,它们仍然可能不相等。

在您的示例中,您定义了 __ hash __ __ eq __ 来完成不同的事情。散列仅取决于多米诺骨牌上数字的总和,但平等取决于两个单独的数字(按顺序)。这是合法的,因为同样的多米诺骨牌仍然是平等的哈希值。但是,正如我上面所说的,这并不意味着等值多米诺骨牌将被视为平等。一些不平等的多米诺骨牌仍然具有相同的哈希值。但是,平等仍然由 __ eq __ 决定,并且 __ eq __ 依然会依次查看两个数字,所以这就是决定是否他们是平等的。



在我看来,在你的情况下适当的做法是定义 __ hash __ __ eq __ 取决于有序对 - 也就是说,首先比较两个数字中较大的一个,然后比较一下。这将意味着2-1和1-2将被视为相同。


How do __hash__ and __eq__ use in identification in sets? For example some code that should help to solve some domino puzzle:

class foo(object):
    def __init__(self, one, two):
        self.one = one
        self.two = two
    def __eq__(self,other):
        if (self.one == other.one) and (self.two == other.two): return True
        if (self.two == other.one) and (self.one == other.two): return True
        return False
    def __hash__(self):
        return hash(self.one + self.two)

s = set()

for i in range(7):
    for j in range(7):
        s.add(foo(i,j))
len(s) // returns 28 Why?

If i use only __eq__() len(s) equals 49. Its ok because as i understand objects (1-2 and 2-1 for example) not same, but represent same domino. So I have added hash function.
Now it works the way i want, but i did not understand one thing: hash of 1-3 and 2-2 should be same so they should counted like same object and shouldn't added to set. But they do! Im stuck.

解决方案

Equality for dict/set purposes depends on equality as defined by __eq__. However, it is required that objects that compare equal have the same hash value, and that is why you need __hash__. See this question for some similar discussion.

The hash itself does not determine whether two objects count as the same in dictionaries. The hash is like a "shortcut" that only works one way: if two objects have different hashes, they are definitely not equal; but if they have the same hash, they still might not be equal.

In your example, you defined __hash__ and __eq__ to do different things. The hash depends only on the sum of the numbers on the domino, but the equality depends on both individual numbers (in order). This is legal, since it is still the case that equal dominoes have equal hashes. However, like I said above, it doesn't mean that equal-sum dominoes will be considered equal. Some unequal dominoes will still have equal hashes. But equality is still determined by __eq__, and __eq__ still looks at both numbers, in order, so that's what determines whether they are equal.

It seems to me that the appropriate thing to do in your case is to define both __hash__ and __eq__ to depend on the ordered pair --- that is, first compare the greater of the two numbers, then compare the lesser. This will mean that 2-1 and 1-2 will be considered the same.

这篇关于蟒蛇。在一组对象中的身份。并散列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆