像这样实现size()
是一个坏主意吗?
function uniqueWordCount(str) {
let set = new Set(str.split(' '));
return set.size;
}
console.log(uniqueWordCount('as as de we re'))
我是否设置了可能造成灾难性的损失?
答案 0 :(得分:4)
__hash__
方法必须满足以下要求才能起作用:
将x,y依次为x == y
,然后为hash(x) == hash(y)
。
在您的情况下,您的类未实现__eq__
,这意味着x == y
当且仅当id(x) == id(y)
时,因此哈希实现满足上述属性。
但是请注意,如果您执行实施__eq__
,则此实施可能会失败。
也:具有“有效” __hash__
和具有 good 哈希值之间是有区别的。例如,以下是 any 类的有效__hash__
定义:
def __hash__(self):
return 1
一个好的散列应该尝试均匀地分布对象,以尽可能避免冲突。通常,这需要更复杂的定义。
我会避免尝试提出公式,而要依靠python内置的hash
函数。
例如,如果您的班级有a
,b
和c
字段,那么我将使用类似__hash__
的名称:
def __hash__(self):
return hash((self.a, self.b, self.c))
对于元组,hash
的定义应足以满足一般情况。
最后:您不应该在可变的类中定义__hash__
(在用于相等性的字段中)。那是因为修改实例会改变其哈希值,这会破坏事情。
答案 1 :(得分:3)
这是毫无意义的还是错误的,具体取决于课程的其余部分。
如果您的对象使用默认的基于身份的==
,则定义此__hash__
是没有意义的。默认的__hash__
也是基于身份的,但是速度更快,并且进行了调整,以避免始终将低位设置为0。使用默认的__hash__
会更简单,更高效。
如果您的对象不使用默认的基于身份的==
,则您的__hash__
是错误的,因为它将与==
不一致。如果对象是不可变的,则应以与__hash__
一致的方式实现==
;如果对象是可变的,则根本不要实现__hash__
(如果需要支持Python 2,请设置__hash__ = None
。)
答案 2 :(得分:1)
这是__hash__
的默认实现。请注意,插入__eq__
会导致默认的__hash__
实现消失。如果您重新实现__hash__
,则所有比较必须的对象必须具有相同的哈希值。
非相等对象也可以具有相同的哈希值。因此,具有返回恒定值的哈希实现始终是安全的。但是,它效率很低。
适用于许多用例的一个很好的默认值是返回__eq__
方法中使用的属性的元组的哈希。例如。
class XYZ:
def __init__(self, val0, val1):
self.val0 = val0
self.val1 = val1
def __eq__(self, other):
return self.val0 == other.val1 and self.val1 == other.val1
def __hash__(self):
return hash((self.val0, self.val1))