带有多维字典的 Python dict.get()
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16003408/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Python dict.get() with multidimensional dict
提问by user2034412
I have a multidimensional dict, and I'd like to be able to retrieve a value by a key:key pair, and return 'NA' if the first key doesn't exist. All of the sub-dicts have the same keys.
我有一个多维字典,我希望能够通过键:键对检索值,如果第一个键不存在,则返回“NA”。所有子字典都具有相同的键。
d = { 'a': {'j':1,'k':2},
'b': {'j':2,'k':3},
'd': {'j':1,'k':3}
}
I know I can use d.get('c','NA')to get the sub-dict if it exists and return 'NA' otherwise, but I really only need one value from the sub-dict. I'd like to do something like d.get('c['j']','NA')if that existed.
我知道我可以d.get('c','NA')用来获取子字典(如果它存在),否则返回“NA”,但我真的只需要子字典中的一个值。d.get('c['j']','NA')如果存在的话,我想做一些类似的事情。
Right now I'm just checking to see if the top-level key exists and then assigning the sub-value to a variable if it exists or 'NA' if not. However, I'm doing this about 500k times and also retrieving/generating other information about each top-level key from elsewhere, and I'm trying to speed this up a little bit.
现在我只是检查顶级键是否存在,然后将子值分配给变量(如果存在)或“NA”(如果不存在)。但是,我这样做了大约 50 万次,并且还从其他地方检索/生成有关每个顶级密钥的其他信息,并且我正在尝试加快速度。
采纳答案by Pavel Anossov
How about
怎么样
d.get('a', {'j': 'NA'})['j']
?
?
If not all subdicts have a jkey, then
如果不是所有的 subdicts 都有一个j键,那么
d.get('a', {}).get('j', 'NA')
To cut down on identical objects created, you can devise something like
要减少创建的相同对象,您可以设计类似
class DefaultNASubdict(dict):
class NADict(object):
def __getitem__(self, k):
return 'NA'
NA = NADict()
def __missing__(self, k):
return self.NA
nadict = DefaultNASubdict({
'a': {'j':1,'k':2},
'b': {'j':2,'k':3},
'd': {'j':1,'k':3}
})
print nadict['a']['j'] # 1
print nadict['b']['j'] # 2
print nadict['c']['j'] # NA
Same idea using defaultdict:
同样的想法使用defaultdict:
import collections
class NADict(object):
def __getitem__(self, k):
return 'NA'
@staticmethod
def instance():
return NADict._instance
NADict._instance = NADict()
nadict = collections.defaultdict(NADict.instance, {
'a': {'j':1,'k':2},
'b': {'j':2,'k':3},
'd': {'j':1,'k':3}
})
回答by mtadd
Rather than a hierarchy of nested dictobjects, you could use one dictionary whose keys are a tuple representing a path through the hierarchy.
dict您可以使用一个字典,而不是嵌套对象的层次结构,它的键是表示通过层次结构的路径的元组。
In [34]: d2 = {(x,y):d[x][y] for x in d for y in d[x]}
In [35]: d2
Out[35]:
{('a', 'j'): 1,
('a', 'k'): 2,
('b', 'j'): 2,
('b', 'k'): 3,
('d', 'j'): 1,
('d', 'k'): 3}
In [36]: timeit [d[x][y] for x,y in d2.keys()]
100000 loops, best of 3: 2.37 us per loop
In [37]: timeit [d2[x] for x in d2.keys()]
100000 loops, best of 3: 2.03 us per loop
Accessing this way looks like it's about 15% faster. You can still use the getmethod with a default value:
以这种方式访问似乎快了 15%。您仍然可以使用get具有默认值的方法:
In [38]: d2.get(('c','j'),'NA')
Out[38]: 'NA'
回答by martineau
Here's a simple and efficient way to do it with ordinary dictionaries, nested an arbitrary number of levels:
这是一种使用普通字典的简单而有效的方法,嵌套任意数量的级别:
d = {'a': {'j': 1, 'k': 2},
'b': {'j': 2, 'k': 3},
'd': {'j': 1, 'k': 3},
}
def chained_get(dct, *keys):
SENTRY = object()
def getter(level, key):
return 'NA' if level is SENTRY else level.get(key, SENTRY)
return reduce(getter, keys, dct)
print chained_get(d, 'a', 'j') # 1
print chained_get(d, 'b', 'k') # 3
print chained_get(d, 'k', 'j') # NA
It could also be done recursively:
它也可以递归完成:
def chained_get(dct, *keys):
SENTRY = object()
def getter(level, keys):
return (level if keys[0] is SENTRY else
'NA' if level is SENTRY else
getter(level.get(keys[0], SENTRY), keys[1:]))
return getter(dct, keys+(SENTRY,))
Although that way of doing it isn't quite as efficient as the former.
尽管这样做的方式不如前者有效。
回答by Shafiq
Another way to get multidimensional dict example ( use get method twice)
另一种获取多维字典示例的方法(使用两次 get 方法)
d.get('a', {}).get('j')

