带有许多键的2d字典将返回相同的值

Kei*_*ith 2 python dictionary python-2.x

我想制作一个每个值有多个键的二维字典.我不想把元组作为一把钥匙.而是使许多键返回相同的值.

我知道如何使用defaultdict创建一个二维字典:

from collections import defaultdict
a_dict = defaultdict(dict)

a_dict['canned_food']['spam'] = 'delicious'
Run Code Online (Sandbox Code Playgroud)

我可以使用一个元组作为一个元组

a_dict['food','canned_food']['spam'] = 'delicious'
Run Code Online (Sandbox Code Playgroud)

但这不允许我做类似的事情

print a_dict['canned_food]['spam']
Run Code Online (Sandbox Code Playgroud)

因为'canned_food'不是关键,元组['food','canned_food']是关键.

我了解到我可以简单地将多个设置为相同的值,如:

a_dict['food']['spam'] = 'delicious'
a_dict['canned_food']['spam'] = 'delicious'
Run Code Online (Sandbox Code Playgroud)

但是这会因为大量按键而变得混乱.在字典的第一维中,每个值需要~25个键.有没有办法写字典,以便元组中的任何键都可以工作?

我以前曾问过这个问题, 但不清楚我想要什么,所以我要重新发布.预先感谢您的任何帮助.

Gar*_*tty 6

这是一个可能的解决方案:

from collections import Iterable

class AliasDefaultDict():
    def __init__(self, default_factory, initial=[]):
        self.aliases = {}
        self.data = {}
        self.factory = default_factory
        for aliases, value in initial:
            self[aliases] = value

    @staticmethod
    def distinguish_keys(key):
        if isinstance(key, Iterable) and not isinstance(key, str):
            return set(key)
        else:
            return {key}

    def __getitem__(self, key):
        keys = self.distinguish_keys(key)
        if keys & self.aliases.keys():
            return self.data[self.aliases[keys.pop()]]
        else:
            value = self.factory()
            self[keys] = value
            return value

    def __setitem__(self, key, value):
        keys = self.distinguish_keys(key)
        if keys & self.aliases.keys():
            self.data[self.aliases[keys.pop()]] = value
        else:
            new_key = object()
            self.data[new_key] = value
            for key in keys:
                self.aliases[key] = new_key
            return value

    def __repr__(self):
        representation = defaultdict(list)
        for alias, value in self.aliases.items():
            representation[value].append(alias)
        return "AliasDefaultDict({}, {})".format(repr(self.factory), repr([(aliases, self.data[value]) for value, aliases in representation.items()]))
Run Code Online (Sandbox Code Playgroud)

哪个可以这样使用:

>>> a_dict = AliasDefaultDict(dict)
>>> a_dict['food', 'canned_food']['spam'] = 'delicious'
>>> a_dict['food']
{'spam': 'delicious'}
>>> a_dict['canned_food']
{'spam': 'delicious'}
>> a_dict
AliasDefaultDict(<class 'dict'>, [(['food', 'canned_food'], {'spam': 'delicious'})])
Run Code Online (Sandbox Code Playgroud)

请注意,有一些边缘情况具有未定义的行为 - 例如对多个别名使用相同的密钥.我觉得这使得这种数据类型对于一般用途来说非常糟糕,我建议你最好不要改变你的程序而不需要这种过于复杂的结构.

另请注意,此解决方案适用于3.x,在2.x以下,您将需要换出strfor basestringself.aliases.keys()for self.aliases.viewkeys().

  • ``&``和``和``是不同的,在这里不相同.问题可能是你使用2.x,而我在3.x上 - 在这种情况下,诀窍是让``self.aliases.viewkeys()``来使它工作.我在那里做的是设置交集,2.x从``keys()``返回的列表没有设置,因此它将失败. (2认同)