我正在构建一个数据结构,并希望构建一个dict映射X-> Y,其中X是我正在行走的数据结构中的一个字段,Y是我正在构建的数据结构中的一个字段在飞行中。 X是一种不可用的类型。
答案 0 :(得分:1)
Java的IdentityHashMap的目的是模拟动态字段。由于Python语言已经直接支持动态属性,因此您不需要地图,只需将Y分配给X的属性
即可x.someSuchRelation = y;
答案 1 :(得分:1)
中平凡:
idmap = {}
idmap[id(x)] = y
使用id
x
作为词典键
答案 2 :(得分:0)
如果将不可用对象包装在另一个对象中,则可以使用常规Python dict
。具体来说,这样的事情:
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
)。如果你不这样做(并且垃圾收集不是问题),那就使用它。
答案 3 :(得分: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