我只是想知道为什么在类的hashCode()方法中使用素数?例如,当使用Eclipse生成我的hashCode()方法时,总会使用素数31:
public int hashCode() {
final int prime = 31;
//...
}
Run Code Online (Sandbox Code Playgroud)
参考文献:
这是关于Hashcode的一篇很好的入门文章和关于我如何找到哈希工作的文章(C#但概念是可转移的): Eric Lippert的GetHashCode指南和规则()
实现具有多个属性的类时(如下面的玩具示例),处理散列的最佳方法是什么?
我猜测,__eq__而__hash__应该是一致的,但如何实现适当的哈希函数,能够处理所有属性?
class AClass:
def __init__(self):
self.a = None
self.b = None
def __eq__(self, other):
return other and self.a == other.a and self.b == other.b
def __ne__(self, other):
return not self.__eq__(other)
def __hash__(self):
return hash((self.a, self.b))
Run Code Online (Sandbox Code Playgroud)
我读到这个问题,元组是可以清洗的,所以我想知道上面的例子是否合情合理.是吗?
Windows XP,Python 2.5:
hash('http://stackoverflow.com') Result: 1934711907
Run Code Online (Sandbox Code Playgroud)
Google App Engine(http://shell.appspot.com/):
hash('http://stackoverflow.com') Result: -5768830964305142685
Run Code Online (Sandbox Code Playgroud)
这是为什么?我怎样才能有一个哈希函数,它可以在不同平台(Windows,Linux,Mac)上提供相同的结果?
我经常使用时髦的东西作为字典的键,因此,我想知道什么是正确的方法 - 这通过为我的对象实现良好的哈希方法.我知道这里提出的其他问题是实现哈希的好方法,但我想了解默认如何__hash__适用于自定义对象,以及是否可以依赖它.
我注意到mutables显然是不可删除的,因为hash({})引发了一个错误...但奇怪的是,自定义类是可以清除的:
>>> class Object(object): pass
>>> o = Object()
>>> hash(o)
Run Code Online (Sandbox Code Playgroud)
那么,有人知道这个默认哈希函数是如何工作的吗?通过理解这一点,我想知道:
如果我将相同类型的对象放入字典的键中,我可以依赖此默认哈希吗?例如:
key1 = MyObject()
key2 = MyObject()
key3 = MyObject()
{key1: 1, key2: 'blabla', key3: 456}
Run Code Online (Sandbox Code Playgroud)
如果我使用不同类型的对象作为字典中的键,我可以依赖它吗?例如
{int: 123, MyObject(10): 'bla', 'plo': 890}
Run Code Online (Sandbox Code Playgroud)
在最后一种情况下,如何确保我的自定义哈希值不会与内置哈希冲突?例如:
{int: 123, MyObject(10): 'bla', MyObjectWithCustomHash(123): 890}
Run Code Online (Sandbox Code Playgroud) 我有一个对象列表,我有一个充满记录的数据库表.我的对象列表有一个title属性,我想从列表中删除任何具有重复标题的对象(保留原始标题).
然后我想检查我的对象列表是否有数据库中任何记录的重复,如果是,请在将它们添加到数据库之前从列表中删除这些项目.
我已经看到了从这样的列表中删除重复项的解决方案:myList = list(set(myList)),但我不确定如何使用对象列表执行此操作?
我也需要维护对象列表的顺序.我也想也许我可以difflib用来检查标题的差异.
我正在研究空间项目中的几何图形,我有不同的几何实体,其中 Point. 有时两个点是相等的,但由于计算导致的数值误差很小,例如1和1.0000000001,所以我实现了__eq__带有math.isclose()函数的方法来解决这个问题。
class Point(object):
def __init__(self, x, y, z):
self.x = x
self.y = y
self.z = z
def __eq__(self, other):
if isinstance(other, Point):
equal_x = math.isclose(other.x, self.x, rel_tol=5e-3, abs_tol=1e-5)
equal_y = math.isclose(other.y, self.y, rel_tol=5e-3, abs_tol=1e-5)
equal_z = math.isclose(other.z, self.z, rel_tol=5e-3, abs_tol=1e-5)
if equal_x and equal_y and equal_z:
return True
return False
Run Code Online (Sandbox Code Playgroud)
__hash__在使用集合和字典时,如何实现该方法以使这两个对象相等?
最终目标是使用以下函数来“统一”此类对象的列表并删除重复项:
def f12(seq):
# from Raymond Hettinger
# https://twitter.com/raymondh/status/944125570534621185
return list(dict.fromkeys(seq))
Run Code Online (Sandbox Code Playgroud) 假设我们有一个像这样的自定义节点类:
class Node:
def __init__(self, val, next, random):
self.val = val
self.next = next
self.random = random
Run Code Online (Sandbox Code Playgroud)
我有一个节点对象,我想将其用作字典的键。
我的理解是,一个对象应该是不可变和可哈希的,才能可靠地用作字典键,因为可变对象可能会导致哈希值发生变化,并且该对象是可变的。
我知道 python 确实允许将自定义可变对象用作字典键,这是如何工作的?
更新:引用的链接不涉及自定义对象的可变性方面。他们只是提供了一种方法来覆盖哈希函数的默认实现。这个问题应该重新打开,因为它与引用的“重复”问题不同。
答案:自定义可变对象的哈希方法的默认实现使用identity,它保证在对象的生命周期内是唯一且恒定的。可变的自定义对象不应该覆盖哈希函数的默认实现。下面提供了更详细的答案。
当阅读有关如何__eq__在 python 中实现时,例如在这个 SO 问题中,您会得到类似的建议
class A(object):
def __init__(self, a, b):
self._a = a
self._b = b
def __eq__(self, other):
return (self._a, self._b) == (other._a, other._b)
Run Code Online (Sandbox Code Playgroud)
现在,我在将其与继承结合时遇到了问题。具体来说,如果我定义一个新类
class B(A):
def new_method(self):
return self._a + self._b
Run Code Online (Sandbox Code Playgroud)
然后我得到这个问题
>>> a = A(1, 2)
>>> b = B(1, 2)
>>> a == b
True
Run Code Online (Sandbox Code Playgroud)
但显然,a和b并不(完全相同)!
__eq__继承的正确实现方法是什么?
假设我有一个程序可以创建一些带有线和点的方案。所有直线均由两点确定。有这些类:
class Coordinates(object):
def __init__(self, x, y):
self.x = x
self.y = y
class Point(object):
def __init__(self, coordinates):
self.coordinates = coordinates
class Line(object):
def __init__(self, coordinates_1, coordinates_2):
self.coordinates_1 = coordinates_1
self.coordinates_2 = coordinates_2
Run Code Online (Sandbox Code Playgroud)
方案采用线列表并创建唯一点列表。
class Circuit(object):
def __init__(self, element_list):
self.line_list = element_list
self.point_collection = set()
self.point_collection = self.generate_points()
def generate_points(self):
for line in self.line_list:
coordinates_pair = [line.coordinates_1, line.coordinates_2]
for coordinates in coordinates_pair:
self.point_collection.add(Point(coordinates))
return self.point_collection
Run Code Online (Sandbox Code Playgroud)
哪些变体能够创建唯一对象的列表或集合?如何不使用集合和排序,仅使用循环和条件来做到这一点?以及如何更简单地做到这一点?
UPD。我附加的代码无法正常工作。我尝试在 Point 类中添加hash和eq方法:
class Point(object):
def __init__(self, coordinates):
self.coordinates = coordinates …Run Code Online (Sandbox Code Playgroud) 我读到这里(从这里):
用户定义的类默认具有
__eq__()和__hash__()方法。使用它们,所有对象比较不相等(除了它们本身)并x.__hash__()返回适当的值,以使x == y暗示x为y和hash(x)== hash(y)。
我想知道__eq__()默认情况下该方法是否定义为:
def __eq__(self, other):
return hash(self) == hash(other)
Run Code Online (Sandbox Code Playgroud)