python 字典中的键
Keys in python dictionaries
我遇到的问题分布在许多源文件中,我尝试以简单的线性格式重现该问题,但都失败了。尽管如此,我遇到的问题只是简单描述了。
我有一个 class Path
,我为此实现了 __hash__
和 __eq__
我在 dict
中有一个 Path
类型的项目,
证明了这一点
path in list(thedict)
>> True
我确认 path == other
和 hash(path) == hash(other)
和 id(path) == id(other)
其中 other
是直接从 list(thedict.keys())
中取出的项目。然而,我得到以下
path in thedict:
>> False
并在 KeyError
中尝试以下结果
thedict[path]
所以我的问题是,在什么情况下这是可能的?我本以为如果 path
在 list(thedict)
中,那么它必须在 thedict.keys()
中,因此我们必须能够写 thedict[path]
。这个假设有什么问题?
更多信息
如果有帮助,下面列出了相关的 classes。在SpecificationPath
级别观察到上述问题
class Path:
pass
@dataclass
class ConfigurationPath(Path):
configurationName: str = None
def __repr__(self) -> str:
return self.configurationName
def __hash__(self):
return hash(self.configurationName)
def __eq__(self, other):
if not isinstance(other, ConfigurationPath):
return False
return self.configurationName == other.configurationName
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@dataclass
class SpecificationPath(Path):
configurationPath: ConfigurationPath
specificationName: str = None
def __repr__(self) -> str:
return f"{self.configurationPath}.{self.specificationName or ''}"
def __hash__(self):
return hash((self.configurationPath, self.specificationName))
def __eq__(self, other):
if not isinstance(other, SpecificationPath):
return False
if self.configurationPath != other.configurationPath:
return False
if self.specificationName != other.specificationName:
return False
return True
为了回应下面的评论,这是 (Spyder) 调试终端中的输出,其中 pf
是一个对象,其中包含使用路径作为键的 paths
字典和相关对象(self
) 有路径。
In : others = list(pf.paths.keys())
In : other = others[1]
In : self.path is other
Out[1]: True
In : self.path in pf.paths
Out[1]: False
根据 :
The paths do want to be mutable as I am setting specificationName
to None
in places (leaving them Anonymous to be filled out later). Further, it is on an instance where the specificationName
is None
that this occurs, however in my simple test scripts I can get away with setting this to None without an error. Could mutability of the hashable instances cause an error such as this?
这是你的问题。您在创建后立即将这些对象放在 dict
中,而 specificationName
是 None
,因此它存储在 dict
中,哈希码基于 None
(该哈希码缓存在 dict
本身中,并且使用该哈希码是将来查找对象的唯一方法)。如果您随后将其更改为 anything 以产生不同的哈希值(读取几乎所有其他内容),则该对象将存储在与旧哈希码相对应的存储桶中,但将其用于查找计算新的哈希码,找不到那个桶。
如果specificationName
必须是可变的,那么它就不能成为散列的一部分,就这么简单。这可能会增加碰撞,但无济于事;如果不触发这个确切的问题,可变字段不能成为散列的一部分。
我遇到的问题分布在许多源文件中,我尝试以简单的线性格式重现该问题,但都失败了。尽管如此,我遇到的问题只是简单描述了。
我有一个 class Path
,我为此实现了 __hash__
和 __eq__
我在 dict
中有一个 Path
类型的项目,
path in list(thedict)
>> True
我确认 path == other
和 hash(path) == hash(other)
和 id(path) == id(other)
其中 other
是直接从 list(thedict.keys())
中取出的项目。然而,我得到以下
path in thedict:
>> False
并在 KeyError
thedict[path]
所以我的问题是,在什么情况下这是可能的?我本以为如果 path
在 list(thedict)
中,那么它必须在 thedict.keys()
中,因此我们必须能够写 thedict[path]
。这个假设有什么问题?
更多信息
如果有帮助,下面列出了相关的 classes。在SpecificationPath
级别观察到上述问题
class Path:
pass
@dataclass
class ConfigurationPath(Path):
configurationName: str = None
def __repr__(self) -> str:
return self.configurationName
def __hash__(self):
return hash(self.configurationName)
def __eq__(self, other):
if not isinstance(other, ConfigurationPath):
return False
return self.configurationName == other.configurationName
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@dataclass
class SpecificationPath(Path):
configurationPath: ConfigurationPath
specificationName: str = None
def __repr__(self) -> str:
return f"{self.configurationPath}.{self.specificationName or ''}"
def __hash__(self):
return hash((self.configurationPath, self.specificationName))
def __eq__(self, other):
if not isinstance(other, SpecificationPath):
return False
if self.configurationPath != other.configurationPath:
return False
if self.specificationName != other.specificationName:
return False
return True
为了回应下面的评论,这是 (Spyder) 调试终端中的输出,其中 pf
是一个对象,其中包含使用路径作为键的 paths
字典和相关对象(self
) 有路径。
In : others = list(pf.paths.keys())
In : other = others[1]
In : self.path is other
Out[1]: True
In : self.path in pf.paths
Out[1]: False
根据
The paths do want to be mutable as I am setting
specificationName
toNone
in places (leaving them Anonymous to be filled out later). Further, it is on an instance where thespecificationName
isNone
that this occurs, however in my simple test scripts I can get away with setting this to None without an error. Could mutability of the hashable instances cause an error such as this?
这是你的问题。您在创建后立即将这些对象放在 dict
中,而 specificationName
是 None
,因此它存储在 dict
中,哈希码基于 None
(该哈希码缓存在 dict
本身中,并且使用该哈希码是将来查找对象的唯一方法)。如果您随后将其更改为 anything 以产生不同的哈希值(读取几乎所有其他内容),则该对象将存储在与旧哈希码相对应的存储桶中,但将其用于查找计算新的哈希码,找不到那个桶。
如果specificationName
必须是可变的,那么它就不能成为散列的一部分,就这么简单。这可能会增加碰撞,但无济于事;如果不触发这个确切的问题,可变字段不能成为散列的一部分。