即使键存在,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) 也不返回的主要内容,如果未能解决你的问题,请参考以下文章