python字典中的键
我遇到的问题分布在许多源文件中,我试图以简单的线性格式重现该问题的尝试失败了。尽管如此,我遇到的问题还是简单地描述了一下 我有一个类python字典中的键,python,dictionary,hash,Python,Dictionary,Hash,我遇到的问题分布在许多源文件中,我试图以简单的线性格式重现该问题的尝试失败了。尽管如此,我遇到的问题还是简单地描述了一下 我有一个类路径,我为它实现了\uuuuu散列和\uuuuuuuuuu均衡 我在dict中有一个Path类型的项目 path in list(thedict) >> True 我验证path==other和hash(path)==hash(other)和id(path)==id(other)其中other是直接从列表(thedict.keys())中提取的项目。然
路径
,我为它实现了\uuuuu散列
和\uuuuuuuuuu均衡
我在dict
中有一个Path
类型的项目
path in list(thedict)
>> True
我验证path==other
和hash(path)==hash(other)
和id(path)==id(other)
其中other
是直接从列表(thedict.keys())中提取的项目。然而,我得到了以下信息
path in thedict:
>> False
并且尝试以下操作会导致keyrerror
thedict[path]
所以我的问题是,在什么情况下这是可能的?如果路径
在列表(thedict)
中,那么它必须在thedict.keys()
中,因此我们必须能够编写thedict[path]
。这个假设有什么错
进一步资料
如果有帮助,下面列出了相关的课程。正是在规范路径
层面上观察到了上述问题
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
是一个对象,包含使用路径作为键的路径
字典,并且该对象(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
Per:
当我将specificationName
设置为None
时,路径确实希望是可变的(让它们匿名,待以后填写)。此外,在specificationName
为None
的情况下会发生这种情况,但是在我的简单测试脚本中,我可以将其设置为None而不会出错。散列实例的可变性会导致这样的错误吗
这是你的问题。创建后立即将这些对象放入dict
中,而specificationName
是None
,因此它以None
为基础存储在dict
中(该哈希代码缓存在dict
本身中,使用该哈希代码是将来查找对象的唯一方法)。如果随后将其更改为产生不同哈希值的任何内容(读取几乎所有其他内容),对象存储在与旧哈希代码对应的bucket中,但使用它进行查找会计算新哈希代码,并且找不到该bucket
如果specificationName
必须是可变的,那么它就不能成为散列的一部分,就这么简单。这可能会增加冲突,但也没什么帮助;可变字段不能成为散列的一部分,而不会触发这个确切的问题。路径可变吗?小挑剔:当isinstance
检查失败时,你会将返回NotImplemented
,而不是False
;这将允许右侧类(如果它与左侧不相同)尝试比较(如果两者都返回NotImplemented
,Python将其转换为False
)@tdelaney不是真的,因为我在那本字典里有几个条目。这些不是类变量,因为我使用的是dataclass机制,它将它们转换成实例变量。注意:你手动实现\uuuuueq\uuuuuuuuu
和\uuuuuuuuuuu散列\uuuuu
有什么原因吗r不做任何更改;将其设置为@dataclass(freezed=True)
也会为您生成\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
(@dataclass(unsafe\uhash=True)
也会这样做,但会让您的实例可变,而散列实例不应该是可变的)。“路径-那么它们就不应该是可散列的。变异会破坏散列。另外,避免实现你自己的\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。但是,让数据类
为您做这件事要好得多。虽然他们不建议这样做,但他们确实注意到,您甚至可以通过将属性定义初始化为字段(hash=False)
(可能需要您使用@dataclass(unsafe\u hash=True)来从生成的哈希中省略特定字段)
而不是@dataclass(freezed=True)
来支持OP的可变字段的情况,该字段不应该是散列的一部分),这将允许dataclass
生成\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu