【问题标题】:How to check if a tuple key is in a dict with O(1) time?如何检查元组键是否在 O(1) 时间的字典中?
【发布时间】:2022-02-03 01:11:17
【问题描述】:

我正在尝试在 Python 中实现哈希表/哈希映射。

假设我使用元组作为键:

hashTable = {}
node = [1, 2, 3]

print(hashTable[tuple(node)]) # throws an error
hashTable[tuple(node)] = True
print(hashTable[tuple(node)]) # prints TRUE

我想在添加之前检查 hashTable 中是否存在元素。我尝试使用所有 False 值初始化字典。

hashTable = {}
for i in range(1000):
    hashTable[i] = False

因此,这将创建一个大小为 1000 的哈希表,其中每个插槽都设置为 FALSE。但是,如果我尝试检查哈希表中是否存在不存在的元素:

print(hashTable[tuple(node)])

我得到了和以前一样的错误。

如何做到这一点?我认为这可以使用in 遍历字典,但这不会首先破坏使用哈希表的全部目的吗?

【问题讨论】:

  • “我认为这可以通过 in 迭代 dict 来工作,但这不会首先破坏使用哈希表的全部目的吗?”不,你为什么认为它会那样工作???有效检查字典成员资格的方法是使用key in my_dict
  • 所有字典键查找是O(1)(假设你自己没有写一个)。另请注意,in 不会迭代字典。
  • 您对hashTable 的实例化创建了一个int: bool 形式的Python 字典,这意味着当您访问其中的一个元素时,您会执行hashTable[SOME_NUMBER] 那么您为什么要查找一个元组呢?
  • 除了下面的好答案之外,如果您确实需要使用默认值初始化不存在的键,请使用 defaultdict 而不是插入所有可能的值。
  • @martineau 并不是全部。哈希计算可能需要任意长的时间,哈希冲突可以使搜索线性时间,并且匹配哈希需要通过相等性检查来确认,因此它还取决于对象比较的速度。 (当然在大多数情况下,我也认为它是 O(1),只是说因为你强调了这么多)。

标签: python dictionary hashtable


【解决方案1】:

访问密钥与检查密钥是否存在类似,但不一定相同。要检查某个键是否在字典中,请通过 in 运算符使用 dict.__contains__。要检查它是否丢失,请使用not in 运算符:

key = tuple(node)
if key not in hashTable:
    hashTable[key] = value

话虽如此,一个完全有效的检查收容方法是尝试访问:

key = tuple(node)
try:
    # attempt to use hashTable[key]
except KeyError:
    # Do something with missing key

在需要两条路径时这样做的好处是您只需要访问字典一次而不是两次。

尽量避免一遍又一遍地打电话给tuple(node):它不是免费的。如果可以,将node 生成为tuple,这样做。如果不是,请执行一次转换并使用转换后的值。

【讨论】:

    【解决方案2】:

    您可以使用in 运算符来确定字典中的成员身份:

    例如

    if tuple(node) in hashTable:
         x = hashTable[tuple(node)]
         ...
    

    【讨论】:

    • 不仅仅是一个关键字,in 是一个运算符
    • 已编辑,谢谢。
    【解决方案3】:

    您可以尝试获取密钥,如果它不在字典中,则返回一个默认值,可能是None

    x = hashTable.get(node, default=None)
    

    【讨论】:

      猜你喜欢
      • 2015-11-26
      • 1970-01-01
      • 1970-01-01
      • 2014-08-07
      • 2011-10-02
      • 2022-01-01
      • 2012-03-27
      • 2016-03-20
      • 2011-11-03
      相关资源
      最近更新 更多