这是一个可能的解决方案:
from collections import Iterableclass 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()]))可以这样使用:
>>> a_dict = AliasDefaultDict(dict)>>> a_dict['food', 'canned_food']['spam'] = 'delicious'>>> a_dict['food']{'spam': 'delicious'}>>> a_dict['canned_food']{'spam': 'delicious'}>> a_dictAliasDefaultDict(<class 'dict'>, [(['food', 'canned_food'], {'spam': 'delicious'})])请注意,有些边缘情况具有未定义的行为-
例如对多个别名使用相同的键。我觉得这使得该数据类型对于一般用途而言非常糟糕,我建议您最好更改程序,而不需要这种过度复杂的结构。
还要注意该解决方案是3.x中,在2.x中,你将要交换出去
str了
basestring,并
self.aliases.keys()为
self.aliases.viewkeys()。



