2

我正在走一个数据结构,并想构建一个字典映射 X-> Y,其中 X 是我正在走的数据结构中的一个字段,Y 是我正在动态构建的数据结构中的一个字段。X 是不可散列的类型。

4

4 回答 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

使用idofx作为字典键

于 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 回答