2010-08-09 92 views
5
>>> d2 
{'egg': 3, 'ham': {'grill': 4, 'fry': 6, 'bake': 5}, 'spam': 2} 
>>> d2.get('spamx',99) 
99 
>>> d2.get('ham')['fry'] 
6 

我想获得火腿内部油炸的价值,如果没有,请获取值99或88作为第二个示例。但是如何?使用默认值进行Python嵌套字典查找

回答

13
d2.get('ham', {}).get('fry', 88) 

我可能会把它分解成现实生活中的几个陈述。

ham = d2.get('ham', {}) 
fry = ham.get('fry', 88) 
+3

而是'd2.get('ham',{})。get('fry',99)',不是? (DRY!) – mykhal 2010-08-09 06:21:56

+1

让东西可读!=重复你自己。重复你自己的功能是编写一个函数来获得火腿的鱼苗,然后用另一个函数来捕获垃圾邮件,这两个函数都可以写成一个以火腿/垃圾邮件为参数的函数。 – 2010-08-09 06:38:01

+0

@Jesse,以前的版本有两个引用'油炸'和两个引用魔术数字被返回。这个建议是一个明显的改进。 – Oddthinking 2010-08-09 16:44:25

3

对于去上班的默认值正确第一默认需要是一本字典,这样就可以链。获得调用正确如果第一个失败。

d.get('ham',{}).get('fry',88) 

你也可以使用一个尝试,除块

def get_ham_fry() 
    try: 
    return d['ham']['fry'] 
    except AttributeError,e: 
    return 88 
+0

字符串索引会增加一个如果找不到键,则返回“KeyError”;如果该项不支持字符串索引,则返回一个“TypeError”。我认为'AttributeError'只适用于'get'调用。 – 2014-10-20 00:55:38

3

如果你需要做这个有很多,你可以写一个辅助函数

def get_nested(d, list_of_keys, default): 
    for k in list_of_keys: 
     if k not in d: 
      return default 
     d=d[k] 
    return d 

print get_nested(d2,['ham','spam'],99) 
print get_nested(d2,['ham','grill'],99) 
+0

感觉像reduce。'functools.reduce(lambda d',x:d [x] if x in d else default,['ham','spam'],d2)' – kennytm 2010-08-09 07:34:00

+1

@KennyTM,为'['bacon','spam']引发'TypeError' – 2010-08-09 09:14:27

0

下面是处理解决方案with nested dictionaries:

def get(root, *keys): 
    """ 
    Returns root[k_1][k_2]...[k_n] if all k_1, ..., k_n are valid keys/indices. 
    Returns None otherwise 
    """ 
    if not keys: 
     return root 
    if keys[0] not in root: 
     return None 
    if keys[0] in root: 
     return get(root[keys[0]], *keys[1:]) 

用法:

>>> d = {'a': 1, 'b': {'c': 3}} 
>>> get(d, 'b', 'c') 
3 
>>> get(d. 'key that's not in d') 
None 
>>> get(d) 
{'a': 1, 'b': {'c': 3}}