2d字典与许多键将返回相同的值 [英] 2d dictionary with many keys that will return the same value
问题描述
我想为每个值制作一个带有多个键的2d字典。我不想让一个元组成一个关键。但是,请输入许多键将返回相同的值。
我知道如何使用defaultdict制作一个2d字典:
from collections import defaultdict
a_dict = defaultdict(dict)
a_dict ['canned_food'] ['spam'] ='delicious'
我可以使用
pre>
a_dict ['food','canned_food'] ['spam'] ='delicious'
但是这不允许我做一些像
打印a_dict ['canned_food] '垃圾邮件']
因为'canned_food'不是元组['food','canned_food ']是关键。
我已经知道,我可以简单地设置许多相同的值,如:
a_dict ['food'] ['spam'] ='delicious'
/ pre>
a_dict ['canned_food'] ['spam'] ='delicious'
但是,这会让大量的键变得混乱。在字典的第一维中,我需要每个值25个键。有没有办法写字典,使元组中的任何键都可以正常工作?
我问过之前的这个问题,但是我并不清楚我想要什么,所以我正在转发。预先感谢您的任何帮助。
解决方案这是一个可能的解决方案:
code>从集合导入Iterable
class AliasDefaultDict():
def __init __(self,default_factory,initial = []):
self.aliases = {}
self.data = {}
self.factory = default_factory
的别名,初始值:
self [aliases] = value
@staticmethod
def distingu_keys(key):
如果isinstance(key,Iterable)而不是isinstance(key,str):
return set(key)
else:
return { key}
def __getitem __(self,key):
keys = self.distinguish_keys(key)
如果keys& self.aliases.keys():
return self.data [self.aliases [keys.pop()]]
else:
value = self.factory()
self [key] = value
返回值
def __setitem __(self,key,value):
keys = self.distinguish_keys(key)
如果keys& self.aliases.keys():
self.data [self.aliases [keys.pop()]] = value
else:
new_key = object()
self。数据[new_key] =值键
self.aliases [key] = new_key
返回值
def __repr __(self):
representation = defaultdict(list)
为别名,在self.aliases.items()中的值:
表示形式[值] .append(别名)
返回AliasDefaultDict({},{} )。format(repr(self.factory),repr([(aliases,self.data [value])for values,aliases in representation.items()]))
/ pre>
可以这样使用:
> >> 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'})])
请注意,有一些具有未定义行为的边缘案例,例如对多个别名使用相同的密钥。我觉得这使得这种数据类型对于一般使用来说非常可怕,我建议你可能会改变你的程序,而不是需要这种过于复杂的结构。
另请注意,这个解决方案是针对3.x,在2.x之下,您将需要将
str
替换为basestring
和self.aliases.keys()
forself.aliases.viewkeys()
。I want to make a 2d dictionary with multiple keys per value. I do not want to make a tuple a key. But rather make many keys that will return the same value.
I know how to make a 2d dictionary using defaultdict:
from collections import defaultdict a_dict = defaultdict(dict) a_dict['canned_food']['spam'] = 'delicious'
And I can make a tuple a key using
a_dict['food','canned_food']['spam'] = 'delicious'
But this does not allow me to do something like
print a_dict['canned_food]['spam']
Because 'canned_food' is not a key the tuple ['food','canned_food'] is the key.
I have learned that I can simply set many to same value independently like:
a_dict['food']['spam'] = 'delicious' a_dict['canned_food']['spam'] = 'delicious'
But this becomes messy with a large number of keys. In the first dimension of dictionary I need ~25 keys per value. Is there a way to write the dictionary so that any key in the tuple will work?
I have asked this question before but was not clear on what I wanted so I am reposting. Thank you in advance for any help.
解决方案Here is a possible solution:
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()]))
Which can be used like so:
>>> 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'})])
Note there are some edge cases with undefined behavior - such as using the same key for multiple aliases. I feel this makes this data type pretty awful for general use, and I'd suggest that you may be better off changing your program not to need this kind of overly convoluted structure instead.
Also note this solution is for 3.x, under 2.x, you will want to swap out
str
forbasestring
, andself.aliases.keys()
forself.aliases.viewkeys()
.这篇关于2d字典与许多键将返回相同的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!