[英]How to use dict.get() with multidimensional dict?
我有一個多維字典,我希望能夠通過鍵:鍵對檢索值,如果第一個鍵不存在,則返回“NA”。 所有子字典都具有相同的鍵。
d = { 'a': {'j':1,'k':2},
'b': {'j':2,'k':3},
'd': {'j':1,'k':3}
}
我知道我可以使用d.get('c','NA')
來獲取 sub-dict(如果它存在)並返回 'NA' 否則,但我真的只需要 sub-dict 中的一個值。 如果存在,我想做類似d.get('c['j']','NA')
事情。
現在我只是檢查頂級鍵是否存在,然后將子值分配給變量(如果存在)或'NA'
如果不存在)。 但是,我這樣做了大約 50 萬次,並且還從其他地方檢索/生成有關每個頂級密鑰的其他信息,並且我正在嘗試加快速度。
怎么樣
d.get('a', {'j': 'NA'})['j']
?
如果不是所有的 subdicts 都有一個j
鍵,那么
d.get('a', {}).get('j', 'NA')
要減少創建的相同對象,您可以設計類似
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
使用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}
})
這是一種簡單而有效的方法,可以使用嵌套任意數量的級別的普通字典來完成。 示例代碼適用於 Python 2 和 3。
from __future__ import print_function
try:
from functools import reduce
except ImportError: # Assume it's built-in (Python 2.x)
pass
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)
d = {'a': {'j': 1, 'k': 2},
'b': {'j': 2, 'k': 3},
'd': {'j': 1, 'k': 3},
}
print(chained_get(d, 'a', 'j')) # 1
print(chained_get(d, 'b', 'k')) # 3
print(chained_get(d, 'k', 'j')) # NA
它也可以遞歸完成:
# Recursive version.
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,))
雖然這種方法不如第一種有效。
您可以使用一個字典,而不是嵌套的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
以這種方式訪問似乎快了 15%。 您仍然可以使用具有默認值的get
方法:
In [38]: d2.get(('c','j'),'NA')
Out[38]: 'NA'
另一種獲取多維字典示例的方法(使用兩次 get 方法)
d.get('a', {}).get('j')
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.