即使键存在,Python dict.get(k) 也不返回

Posted

技术标签:

【中文标题】即使键存在,Python dict.get(k) 也不返回【英文标题】:Python dict.get(k) returns none even though key exists 【发布时间】:2020-07-21 21:20:27 【问题描述】:

也许我对python的字典理解不好。但这就是问题所在。

字典中是否有一个yolk: shell存在eggs,但eggs.get(yolk) 可以返回None

因此,在一个大代码中,我对字典执行多个get 操作,经过一定的迭代后,我观察到了这种情况。

   >>> for key, value in nodehashes.items():
   ...    print(key, nodehashes.get(key), value)
   ............................
   ...........................
   <Graph.Node object at 0x00000264128C4DA0> 3309678211443697093 3309678211443697093
   <Graph.Node object at 0x00000264128C4DD8> 3554035049990170053 3554035049990170053
   <Graph.Node object at 0x00000264128C4E10> None -7182124040890112571  # Look at this!!
   <Graph.Node object at 0x00000264128C4E48> 3268020121048950213 3268020121048950213
   <Graph.Node object at 0x00000264128C4E80> -1243862058694105659 -1243862058694105659
   ............................
   ............................


乍一看,好像在代码的某个地方,key被删除了,但是nodehashes.items()如何返回正确的key-value对呢?我扫了整个区域,我根本没有弹出一个项目。怎么会这样?

我知道我不发布示例是错误的,但我真的不知道从哪里开始查看代码,节点在开始时是散列的,它们只能通过get 访问。令人惊讶的是,即使 PyCharm 的调试器也显示存在键值对。但是get 返回无。因此,如果其他人之前遇到过这个问题,我会全力以赴。

def __eq__(self, other): 
    if (self.x == other.x) and (self.y == other.y): 
        return True 
    else: 
        return False 

def __hash__(self): 
    return hash(tuple([self.x, self.y]))

【问题讨论】:

这是并发代码吗?是否有可能有另一个线程/...可以在您迭代 nodehashes 时对其进行修改? 不,它不是并发的。 class Node 是否定义了__hash__ 和/或__eq__ 我尝试构建一个可重现的示例,但无法让它重现此场景。 @juanpa.arrivillaga 是的,Node 定义的类都为 `def __eq__(self, other): if (self.x == other.x) and (self.y == other.y ): return True else: return False def __hash__(self): return hash(tuple([self.x, self.y]))` 【参考方案1】:

如果您在可变对象上有自定义 __hash__ 方法,则可以重现该方法:

class A:
    def __hash__(self):
        return hash(self.a)

>>> a1 = A()
>>> a2 = A()
>>> a1.a = 1
>>> a2.a = 2
>>> d = a1: 1, a2: 2
>>> a1.a = 3
>>> d.items()
dict_items([(<__main__.A object at 0x7f1762a8b668>, 1), (<__main__.A object at 0x7f17623d76d8>, 2)])
>>> d.get(a1)
None

您可以看到d.items() 仍然可以访问两个A 对象,但get 无法再找到它,因为hash 的值已更改。

【讨论】:

好吧,任何与相等性不一致的哈希方法。考虑float('nan') 在散列数据结构中的行为。但我怀疑你的猜测是正确的。 @juanpa 不一致是一个问题,但在您的情况下,代码将是完全确定的,它显然不在这里。 嗯,这实际上解释了它,所以我不得不考虑除 hash 方法之外的另一种方法来标识节点。 @JaswantP 您可以使用id(node) 作为您的字典中的键。 @JaswantP 好吧,是的,id 是一样的。不过,我忘记了,如果您定义了 __eq__ 而不是 __hash__,那么 __hash__ 会隐式设置为 None,当您尝试对其进行哈希处理时会引发类型错误。所以你可以只使用__hash__ = object.__hash__ 或自己定义它来返回id(self)

以上是关于即使键存在,Python dict.get(k) 也不返回的主要内容,如果未能解决你的问题,请参考以下文章

Python snippet(代码片段)

39-python基础-python3-字典常用方法-get()

dict.get("A", "B") 从字典中获取值的方法

Python字典包含了以下内置方法

python字典dict的成对运算

字典 get()