2d字典与许多键将返回相同的值 [英] 2d dictionary with many keys that will return the same value

查看:149
本文介绍了2d字典与许多键将返回相同的值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想为每个值制作一个带有多个键的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'
a_dict ['canned_food'] ['spam'] ='delicious'
/ pre>

但是,这会让大量的键变得混乱。在字典的第一维中,我需要每个值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() for self.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 for basestring, and self.aliases.keys() for self.aliases.viewkeys().

这篇关于2d字典与许多键将返回相同的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆