使用默认值查找Python嵌套字典

11
>>> d2
{'egg': 3, 'ham': {'grill': 4, 'fry': 6, 'bake': 5}, 'spam': 2}
>>> d2.get('spamx',99)
99
>>> d2.get('ham')['fry']
6

我想获取火腿里面的炸鱼的值,如果没有,则获取值为99或88,就像第二个例子一样。但是怎么做呢?

5个回答

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

在实际情况下,我可能会将其分解为几个语句。

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

3
更好的写法是 d2.get('ham', {}).get('fry', 99),不要重复自己! - mykhal
1
让代码易读并不等同于重复自己。重复自己的做法是写一个函数来获取火腿炒饭,然后再写另一个函数来获取午餐肉炒饭,而这两个函数可以合并成一个函数,通过参数来区分火腿和午餐肉。 - Jesse Dhillon
@Jesse,奇怪。我也不是。我大约编辑了3或4次才弄对了,但是SO似乎把它合并成了1个,让我看起来比我实际上更果断。 - Oddthinking
@Oddthinking,我认为如果编辑在一定时间窗口内聚集,它们将被折叠。 - Jesse Dhillon
注意:如果d2.get('ham'...)返回的不是字典(如果d2['ham']'other'),则会出现错误。 - Peter Gibson
显示剩余2条评论

5
如果您需要经常执行此操作,可以编写一个帮助函数。
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)

感觉像是 reduce。functools.reduce(lambda d,x: d[x] if x in d else default, ['ham','spam'], d2) - kennytm
1
@KennyTM,对于['bacon','spam']引发了一个TypeError - John La Rooy

4
为了使get的默认值正常工作,第一个默认值应该是一个字典,这样如果第一个失败,你就可以正确地链接.get调用。
d.get('ham',{}).get('fry',88)

你也可以使用try except块

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

1
字符串索引将引发KeyError(如果未找到键)或TypeError(如果该项不支持字符串索引)。我认为AttributeError仅适用于get调用。 - Peter Gibson

1

以下是处理嵌套字典的解决方案:

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}}

0

该问题的另一个解决方案可能是:

从'ham'获取'fry',否则返回88

result = d2['ham'].get('fry', 88)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,