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个键.有没有办法写字典,以便元组中的任何键都可以工作?
我以前曾问过这个问题, 但不清楚我想要什么,所以我要重新发布.预先感谢您的任何帮助.
这是一个可能的解决方案:
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 basestring和self.aliases.keys()for self.aliases.viewkeys().