Python的 - 大约哈希和问题`None`
为什么None
哈希-1042159082
(我发现等于字节数在技嘉否定)?Python的 - 大约哈希和问题`None`
我知道这并没有真正影响我的代码,但我很好奇。
哈希值是用于字典键查找窗口,所以我决定尝试:
>>> D = {-1042159082: 'Hello', None: 'Hi'}
>>> D[None]
'Hi'
>>> D[-1042159082]
'Hello'
>>>
我明白这是Python的看到两个相同的哈希值,然后检查类型,看看什么是什么。是对的吗?
>>> {False: 'Hello', 0: 'Hi'}
{False: 'Hi'}
>>> {0: 'Hi', False: 'Hello'}
{0: 'Hello'}
这很奇怪。更重要的是,第一个键被保留,第二个值被保留。
这是巫术,或者可能有人帮助我明白了吗?
没有,即使两个对象碰巧具有相同的哈希,他们仍然不会导致键冲突。 Python检测这个并且解决它(尽管请不要问我如何)。
但False
相同0
和True
是一样的1
,所以当你无论是在一个字典建设使用,你使用相同的密钥将另一项目时更新值。
你不能和不应该依赖于对Python对象特定的哈希值。它是实现和机器相关的。在我的机器:
>>> hash(None)
268532216
至于填充dict
对象去(没有hash
对象在Python),也许下面将帮助:
>>> False == 0
True
>>> {0: 'Hello', 0: 'Hi'}
{0: 'Hi'}
>>> {0: 'Hi', 0: 'Hello'}
{0: 'Hello'}
>>> {False: 'Hello', False: 'Hi'}
{False: 'Hi'}
>>> {False: 'Hi', False: 'Hello'}
{False: 'Hello'}
当使用dict
构造函数时,提供两个key=value
对,但它们都具有相同的密钥(即可哈希值),因此,由于字典中的键值必须是唯一的,最后一个值是保存的值。换句话说,每一个构造函数上面创建一个项目字典的:
>>> print {False: 'Hello', 0: 'Hi'}
{False: 'Hi'}
更多信息,请参见here。
你如何看待没有哈希值?
>>> d = {None:'hi'}
>>> d.get(-1042159082)
>>> d.get(None)
'hi'
>>>
>>> hash(None)
268532214
>>>
我不会依赖散列的值无,永远。
至于使用文字的字典解析,我假设在内部定义一个'等于'另一个的关键,只是做一个更新而不是直接添加。
>>> class Key(object):
... key = '1'
... def __hash__(self):
... return 1
... def __eq__(self, other):
... return hash(self) == hash(other)
...
>>> class FakeKey(Key):
... key = '2'
...
>>> k = Key()
>>> >>> fk = FakeKey()
>>> d = {k:k,fk:fk}
>>> d
{<__main__.Key object at 0x100489f10>: <__main__.FakeKey object at 0x100489fd0>}
>>> ref = d[k]
>>> ref.key
'2'
>>> d.keys()[0].key
'1'
>>>
出现我是对的(只出现)。
我没有数字,我只是在我的解释器中键入了'hash(None)'。查看Ned的回答来回答你关于'hash'的问题。另外,你为什么不依赖散列'None'?这是一个内存中的对象,还是Python文档在某处说的? – orokusaki 2011-03-27 06:34:22
我的意思是,我不会依赖散列值(无)是一致的。在字典中使用无可以,但使用hash(None)产生的值不是。 – 2011-03-27 06:41:44
而且实际上很少有理由需要知道Python对象的散列值。如果你认为你这样做,那么你可能会考虑错误的方式。 http://docs.python.org/library/functions.html#hash – 2011-03-27 06:50:46
这一切都是真实的,但请记住,在OP的示例中不存在哈希碰撞:它是* same *键值。在Python中,False等于整数0. – 2011-03-27 06:38:45
Ned Deily:谢谢,澄清了答案即将回答的关于碰撞的答案部分。 – Abbafei 2011-03-27 06:48:17
@Ned - 你说错了。 'None'散列到被重用为另一个键的同一个负整数,但两个键都保留在字典中。这与'False':'0'例子不一致,其中相同的行为导致了不同的结果。 @阿不菲,谢谢你的正确答案。我研究了源代码C,看到与'Py_None'有关的条件是非常有趣的。 – orokusaki 2011-03-27 18:22:48