Python-hash()和dict

Python-hash()和dict,python,dictionary,hash,Python,Dictionary,Hash,如果我们有两个单独的dict,它们都具有相同的键和值,那么当我们打印它们时,它们将按照预期的不同顺序出现。 那么,假设我想在那些dict上使用hash(): hash(frozenset(dict1.items())) hash(frozenset(dict2.items())) 我这样做是为了创建一个新的dict,并将hash()值创建为新键。 即使在打印dict时显示不同,由hash()创建的值始终相等?如果否,如何使其始终相同,以便我能够成功地进行比较?如果键和值哈希相同,frozens

如果我们有两个单独的
dict
,它们都具有相同的
键和
值,那么当我们打印它们时,它们将按照预期的不同顺序出现。
那么,假设我想在那些
dict
上使用
hash()

hash(frozenset(dict1.items()))
hash(frozenset(dict2.items()))
我这样做是为了创建一个新的
dict
,并将
hash()
值创建为新键。

即使在打印
dict
时显示不同,由
hash()
创建的值始终相等?如果否,如何使其始终相同,以便我能够成功地进行比较?

如果键和值
哈希
相同,
frozenset
被设计为基础值的稳定且唯一的表示形式:

两个集合是相等的当且仅当每个集合的每个元素都包含在另一个集合中(每个集合都是另一个集合的子集)

以及:

比较相等的可散列对象必须具有相同的散列值

因此,根据定义,
frozenset
s具有相等的、可散列的元素是相等的,散列为相同的值。只有在生成的
frozenset
中包含一个不遵守哈希和相等规则的用户定义类时,才会违反此规则(但这样会出现更大的问题)

请注意,这并不意味着它们将以相同的顺序迭代或生成相同的
repr
;多亏了散列冲突上的链接,由相同元素以不同顺序构造的两个
frozenset
s不需要以相同顺序迭代。但它们仍然是相等的,散列也是相同的(精确的输出和顺序取决于实现,在不同版本的Python之间可能很容易发生变化;这恰好可以在我的Py 3.5安装上工作,以创建所需的“不同迭代顺序”行为):

>>frozenset([1,9])
frozenset({1,9})
>>>frozenset([9,1])
frozenset({9,1})#>>散列(frozenset([1,9]))
-7625378979602737914
>>>散列(frozenset([9,1]))
-7625378979602737914#>>冻结集([1,9])==冻结集([9,1])

True#如果键和值
散列
相同,
冻结集
被设计为基础值的稳定且唯一的表示形式:

两个集合是相等的当且仅当每个集合的每个元素都包含在另一个集合中(每个集合都是另一个集合的子集)

以及:

比较相等的可散列对象必须具有相同的散列值

因此,根据定义,
frozenset
s具有相等的、可散列的元素是相等的,散列为相同的值。只有在生成的
frozenset
中包含一个不遵守哈希和相等规则的用户定义类时,才会违反此规则(但这样会出现更大的问题)

请注意,这并不意味着它们将以相同的顺序迭代或生成相同的
repr
;多亏了散列冲突上的链接,由相同元素以不同顺序构造的两个
frozenset
s不需要以相同顺序迭代。但它们仍然是相等的,散列也是相同的(精确的输出和顺序取决于实现,在不同版本的Python之间可能很容易发生变化;这恰好可以在我的Py 3.5安装上工作,以创建所需的“不同迭代顺序”行为):

>>frozenset([1,9])
frozenset({1,9})
>>>frozenset([9,1])
frozenset({9,1})#>>散列(frozenset([1,9]))
-7625378979602737914
>>>散列(frozenset([9,1]))
-7625378979602737914#>>冻结集([1,9])==冻结集([9,1])

因此,从第二行中考虑<代码> KE1从第一行和<代码> KEY2<代码>。如果我使用
If(key1==key1)
将始终为真?只是确定一下,对不起,我缺乏经验。为什么会有不同的订单?散列或字典插入没有随机性,对吗?嗯,
dicts
没有指定的顺序,对吗?我想知道这是否可以更改
散列
value@JayanthKoushik:如果存在哈希冲突,并且
dict
s的历史记录不同,则使用相同键的
dict
s的顺序可以更改。如果将具有相同散列的两个对象(经过缩减以匹配桶数)插入
dict
(或
set
/
frozenset
)、
a
b
,并在不同的集合中插入
b
,然后插入
a
,则这两个项的相对顺序将不同。由于使用了虚拟占位符来确保链接的值不会丢失,如果值被删除,而不仅仅是添加,则情况会更加复杂。举个简单的例子。@AdrianoFerrariCardoso:它不能。如<代码> > FurZeNSET/<代码>和哈希保证保证了哈希是一致的,即使排序可能根据“<代码> FROZSENSET ”的构造而有所不同。因此,从第二行中考虑<代码> KEY1<代码> >第一代码> <代码> KEY2<代码>。如果我使用
If(key1==key1)
将始终为真?只是确定一下,对不起,我缺乏经验。为什么会有不同的订单?散列或字典插入没有随机性,对吗?嗯,
dicts
没有指定的顺序,对吗?我想知道这是否可以更改
散列
value@JayanthKoushik:如果存在哈希冲突,并且
dict
s的历史记录不同,则使用相同键的
dict
s的顺序可以更改。如果将具有相同散列的两个对象(经过缩减以匹配桶数)插入
dict
(或
set
/
frozenset
)、
a
b
,并在不同的集合中插入
b
,然后插入
a
,则这两个项的相对顺序将不同。由于使用了虚拟占位符来确保链接的值不会丢失,如果值被删除,而不仅仅是添加,则情况会更加复杂。举个简单的例子。@AdrianoFerrariCardoso:它不能。如中所述,
frozenset
和hashable保证
>>> frozenset([1,9])
frozenset({1, 9})
>>> frozenset([9,1])
frozenset({9, 1}) # <-- Different order; consequence of 8 buckets colliding for 1 and 9
>>> hash(frozenset([1,9]))
-7625378979602737914
>>> hash(frozenset([9,1]))
-7625378979602737914 # <-- Still the same hash though
>>> frozenset([1,9]) == frozenset([9,1])
True # <-- And still equal