首页 > 解决方案 > 无序列表作为 dict 键

问题描述

我希望能够做类似的事情:

foo = Counter(['bar', 'shoo', 'bar'])
tmp = {}
tmp[foo] = 5

换句话说,是否有一个可散列的等价物Counter?请注意,我不能使用frozenset,因为我有重复的元素,我想保留在密钥中。

编辑: 在我的实际应用程序中, foo 中的对象可能无法相互比较,因此无法对列表进行排序。

标签: pythonpython-3.xdictionary

解决方案


您似乎需要一种使用无序键值对作为键的方法。Afrozenset可能是要走的路,尽管您必须从 ofitemsCounter不是它的keys.

foo = Counter(['bar', 'shoo', 'bar'])
tmp = {}
tmp[frozenset(foo.items())] = 5

# tmp: {frozenset({('bar', 2), ('shoo', 1)}): 5}

如果这令人满意,您可以通过定义自己的映射类型来实现此转换,如下所示:

from collections import Counter

class CounterDict:
    def __init__(self):
        self.data = {}

    def __setitem__(self, key, value):
        if isinstance(key, Counter):
            self.data[frozenset(key.items())] = value
        else:
            raise TypeError

    def __getitem__(self, key):
        if isinstance(key, Counter):
            return self.data[frozenset(key.items())]
        else:
            raise TypeError

foo = Counter(['bar', 'shoo', 'bar'])
tmp = CounterDict()
tmp[foo] = 42
tmp[foo] # 42

您可以通过CounterDict创建collections.UserDict.


推荐阅读