我对哈希表和哈希的工作方式非常熟悉,但我正在努力完全理解 O(1)是如何完全来自的。
set1 = {'s','t'}
print('x' in set1)
print('s' in set1)
set2 = {'s'}
print('s' in set2)
我被告知检查{1}是否在set1中,if是否检查's'
哈希的内存分配,并检查它是否在 O(1)中的set1中并返回布尔值。因此有两个O(1)操作,但我的问题是:哈希实际上是如何深入工作的。我的意思是,当您对's'
进行哈希时,该哈希值是's'
和set1
,并且您正在检查set2
是否为set1
}或set1
,或者每个集合都有set2
的不同哈希值,并且您正在为每个不同的集合检查's'
的哈希值。
答案 0 :(得分:0)
Python dict
本质上是hash table。基本上,密钥通过散列函数转换为表位置;由于多个键可能具有相同的值,因此必须有一些机制来检测冲突(多个具有相同键的键)并向下移动一系列备用条目,直到找到正确的键。
对于dict
,密钥单元格在找到时与值相关联。对于set
,没有值:密钥要么属于集合要么不属于集合。
因此,散列行为允许在恒定时间内消除大多数可能的值(假设冲突不常出现问题,并且Python会在可能发生的情况下重新分配存储空间。)
答案 1 :(得分:0)
我建议你阅读这篇previous question,它将详细解释Python中的散列。
答案 2 :(得分:0)
当Python创建一个字符串时,它基于字符串值。因此,分配给不同变量的's'
和's'
都具有相等的哈希值。因此:
>>> a = 's'
>>> b = 's'
>>> hash(a) == hash(b)
True
但请注意,它们可能并不总是指向内存中的相同字符串:
>>> a = 'this is some really long string'
>>> b = 'this is some really long string'
>>> id(a)
47002352L
>>> id(b)
47002608L
答案 3 :(得分:0)
(不可变)对象在其整个生命周期中始终具有相同的哈希值。 set1
和set2
之间的哈希值相同 - 这允许在集合之间执行union
和intersection
之类的操作,以及确定成员是否为除了其他内容之外,在集合中是独一无二的。
>>> first_dict = {"s":"s".__hash__(), "t":"t".__hash__()}
>>> second_dict = {"s":"s".__hash__()}
>>> first_dict
{'s': -638743784, 't': 711199131}
>>> second_dict
{'s': -638743784}
您可以拥有内存中不同对象的相同字符串。但由于它们是相同的字符串,因此它们会相同。
>>> id(a)
7858120
>>> id(b)
7858624
>>> a.__hash__()
-1117164856
>>> b.__hash__()
-1117164856
如果对象具有在其生命周期内永远不会更改的哈希值(它需要哈希()方法),并且可以与其他对象进行比较(它需要),则该对象是可清除的eq ()方法)。比较相等的Hashable对象必须具有相同的哈希值。
Hashability使对象可用作字典键和set成员,因为这些数据结构在内部使用哈希值。
所有Python的不可变内置对象都是可清除的,而没有可变容器(例如列表或字典)。默认情况下,作为用户定义类实例的对象是可清除的;它们都比较不等(除了它们自己),它们的哈希值来自它们的id()。