我正在走一个数据结构,并想构建一个字典映射 X-> Y,其中 X 是我正在走的数据结构中的一个字段,Y 是我正在动态构建的数据结构中的一个字段。X 是不可散列的类型。
问问题
462 次
4 回答
1
Java 的 IdentityHashMap 的目的是模拟动态字段。由于 Python 语言已经直接支持动态属性,所以不需要映射,只需将 Y 分配给 X 的属性
x.someSuchRelation = y;
于 2013-06-11T21:35:41.817 回答
1
dict
如果您将不可散列的对象包装在另一个对象中,则可以为此使用常规 Python 。具体来说,是这样的:
class Wrapper(object):
def __init__(self, o):
self.o = o
def __hash__(self):
return id(self.o)
def __eq__(self, o):
return hash(self) == hash(o)
然后就像使用它一样some_dict[Wrapper(unhashable_object)]
。
id(o)
如果您之后还需要能够访问对象本身(key.o
显然是),那么这是一种比仅使用作为键更有用的方法。如果您不这样做(并且垃圾收集不是问题),请使用它。
于 2013-06-11T21:57:02.037 回答
0
琐碎:
idmap = {}
idmap[id(x)] = y
使用id
ofx
作为字典键
于 2013-06-11T21:47:44.380 回答
0
通常,针对这个常见问题的破碎解决方案是使用id
. 它被破坏是因为id
仅在现有对象中是唯一的,因此可能会随机发生以下情况:
>>> idmap = {}
>>> idmap[id(x)] = 42
>>> del x
>>> z = SomeObject()
>>> z in idmap
True
无需显式del
声明,只需在函数内向 idmap 添加一个键即可导致相同的结果:
>>> def add_smthg(idmap):
>>> x = SomeObject()
>>> idmap[id(x)] = 42
>>> idmap = {}
>>> add_smthg(idmap)
>>> z = SomeObject()
>>> z in idmap
True
为避免这种情况,您必须保留您插入的每个对象的引用。恕我直言,唯一可行的选择是创建新的字典/集合类:
class IdentitySet:
def __init__(self, items=None):
if items is None:
items = []
self._identities = {id(item): item for item in items}
def add(self, item):
self._identities[id(item)] = item
def __delitem__(self, item):
del self._identities[id(item)]
def __contains__(self, item):
return id(item) in self._identities
class IdentityDict:
def __init__(self, pairs=None):
if pairs is None:
pairs = []
self._identities = IdentitySet(k for k, _ in pairs)
self._values = {id(k): v for k, v in pairs}
def __getitem__(self, item):
return self._values[id(item)]
def __setitem__(self, item, value):
self._identities.add(item)
self._values[id(item)] = value
def __delitem__(self, item):
del self._identities[item]
del self._values[id(item)]
def __contains__(self, item):
return item in self._identities
于 2020-11-06T10:14:43.170 回答