当前位置: 首页 > 面试题库 >

不可变的字典,仅用作其他字典的键

谢昊乾
2023-03-14
问题内容

我需要实现一个可哈希的字典,因此我可以将一个字典用作另一个字典的键。

但是我从一位同事那里得到了一个通知,说“它并不是真正不变的,因此并不安全。您可以使用它,但是它的确使我感到自己像个可悲的熊猫。

因此,我开始环顾四周以创建一个不可变的对象。我没有必要将“ key-dict”与另一个“ key-dict”进行比较。它的唯一用途是用作另一本词典的键。

我想出了以下几点:

class HashableDict(dict):
    """Hashable dict that can be used as a key in other dictionaries"""

    def __new__(self, *args, **kwargs):
        # create a new local dict, that will be used by the HashableDictBase closure class
        immutableDict = dict(*args, **kwargs)

        class HashableDictBase(object):
            """Hashable dict that can be used as a key in other dictionaries. This is now immutable"""

            def __key(self):
                """Return a tuple of the current keys"""
                return tuple((k, immutableDict[k]) for k in sorted(immutableDict))

            def __hash__(self):
                """Return a hash of __key"""
                return hash(self.__key())

            def __eq__(self, other):
                """Compare two __keys"""
                return self.__key() == other.__key() # pylint: disable-msg=W0212

            def __repr__(self):
                """@see: dict.__repr__"""
                return immutableDict.__repr__()

            def __str__(self):
                """@see: dict.__str__"""
                return immutableDict.__str__()

            def __setattr__(self, *args):
                raise TypeError("can't modify immutable instance")
            __delattr__ = __setattr__

        return HashableDictBase()

我使用以下工具测试功能:

d = {"a" : 1}

a = HashableDict(d)
b = HashableDict({"b" : 2})

print a
d["b"] = 2
print a

c = HashableDict({"a" : 1})

test = {a : "value with a dict as key (key a)",
        b : "value with a dict as key (key b)"}

print test[a]
print test[b]
print test[c]

这使:

{‘a’:1}
{‘a’:1}
以dict为键(键a)的
值以dict为键(键b)的
值以dict为键(键a)的值

作为输出

这是我可以使用的“最佳”不可变字典,它满足我的要求吗?如果没有,什么是更好的解决方案?


问题答案:

如果仅将它用作其他项的密钥dict,则可以这样做frozenset(mutabledict.items())。如果您需要访问基础映射,则可以将其用作的参数dict

mutabledict = dict(zip('abc', range(3)))
immutable = frozenset(mutabledict.items())
read_frozen = dict(immutable)
read_frozen['a'] # => 1

请注意,您还可以将此方法与从派生的类结合dict使用,并frozenset在禁用的同时将用作哈希的源__setitem__,如另一个答案中所建议。



 类似资料:
  • 问题内容: 我想将JSON数据存储在Python Pandas DataFrame中 我的JSON数据是像这样的字典的字典 我这样做是为了将数据放入DataFrame 我明白了 我的问题是我的DataFrame包含字典而不是值。 我想知道如何使用Pandas DataFrame管理多维数据(超过2个维度…这里有3个维度)。 DataFrame中的每个字典都有相同的键。 问题答案: df = pd.

  • 有一个问题,为什么他们要求在字典中使用不可变对象作为键。 当我最近使用字典(显然不是为了哈希表)将Xml节点对象作为键放置时,这个问题实际上进入了我的脑海。然后,我在使用过程中多次更新节点。 那么,“使用不可变键”到底意味着什么呢?

  • Dictionary《'TKey, 'TValue》类是F#地图数据结构的可变模拟,包含许多相同的功能。 从F#中的Map章节重述,地图是一种特殊的集合,它将值与键相关联。 创建一个可变字典 使用new关键字创建可变字典并调用列表的构造函数。 以下示例演示了这一点 - open System.Collections.Generic let dict = new Dictionary<string,

  • 我有一个包含字典作为其元素的列表 我想从dict_1变量中得到这样的输出 帮助我知道在这种情况下我该怎么做。

  • rank ▲ ✰ vote url 11 867 379 1107 url 用字典的值对字典进行排序 我有个字典,字典的值来自于数据库:一个是字符串,一个是数字.字符串是唯一的,所以键就是字符串. 我可以用键来排序,但是怎么用值来排序呢? 注:我已经看过另一个问题怎样对列表中的字典的键值对字典进行排序?,或许这种方法可以,但是我确实只需要一个字典,我想看看还有其他更好的方法. 对字典进行排序是不可

  • dict的很多方法跟list有类似的地方,下面一一道来,并且会跟list做一个对比 嵌套 嵌套在list中也存在,就是元素是list,在dict中,也有类似的样式: >>> a_list = [[1,2,3],[4,5],[6,7]] >>> a_list[1][1] 5 >>> a_dict = {1:{"name":"qiwsir"},2:"python","email":"qiwsir@gm