我有一本嵌套的字典。是否只有一种方法可以安全地传递价值观?
try:
example_dict['key1']['key2']
except KeyError:
pass
或者python有一个类似get()的方法用于嵌套字典?
我有一本嵌套的字典。是否只有一种方法可以安全地传递价值观?
try:
example_dict['key1']['key2']
except KeyError:
pass
或者python有一个类似get()的方法用于嵌套字典?
当前回答
我的实现下降到子字典,忽略None值,但失败与TypeError如果发现任何其他
def deep_get(d: dict, *keys, default=None):
""" Safely get a nested value from a dict
Example:
config = {'device': None}
deep_get(config, 'device', 'settings', 'light')
# -> None
Example:
config = {'device': True}
deep_get(config, 'device', 'settings', 'light')
# -> TypeError
Example:
config = {'device': {'settings': {'light': 'bright'}}}
deep_get(config, 'device', 'settings', 'light')
# -> 'light'
Note that it returns `default` is a key is missing or when it's None.
It will raise a TypeError if a value is anything else but a dict or None.
Args:
d: The dict to descend into
keys: A sequence of keys to follow
default: Custom default value
"""
# Descend while we can
try:
for k in keys:
d = d[k]
# If at any step a key is missing, return default
except KeyError:
return default
# If at any step the value is not a dict...
except TypeError:
# ... if it's a None, return default. Assume it would be a dict.
if d is None:
return default
# ... if it's something else, raise
else:
raise
# If the value was found, return it
else:
return d
其他回答
对于嵌套的字典/JSON查找,可以使用dictor
PIP安装指示器
dict对象
{
"characters": {
"Lonestar": {
"id": 55923,
"role": "renegade",
"items": [
"space winnebago",
"leather jacket"
]
},
"Barfolomew": {
"id": 55924,
"role": "mawg",
"items": [
"peanut butter jar",
"waggy tail"
]
},
"Dark Helmet": {
"id": 99999,
"role": "Good is dumb",
"items": [
"Shwartz",
"helmet"
]
},
"Skroob": {
"id": 12345,
"role": "Spaceballs CEO",
"items": [
"luggage"
]
}
}
}
要获得龙星的物品,只需提供一个点分隔的路径,即
import json
from dictor import dictor
with open('test.json') as data:
data = json.load(data)
print dictor(data, 'characters.Lonestar.items')
>> [u'space winnebago', u'leather jacket']
如果键不在路径中,您可以提供回退值
你还有很多选择,比如忽略字母大小写,使用'以外的其他字符。作为路径分隔符,
https://github.com/perfecto25/dictor
从Python 3.4开始,你可以使用suppress (KeyError)来访问嵌套的json对象,而不用担心KeyError
from contextlib import suppress
with suppress(KeyError):
a1 = json_obj['key1']['key2']['key3']
a2 = json_obj['key4']['key5']['key6']
a3 = json_obj['key7']['key8']['key9']
Techdragon提供。看看他的回答,了解更多细节:https://stackoverflow.com/a/45874251/1189659
你可以用虚线:
PIP安装
from dotted.collection import DottedDict
assert DottedDict(dict(foo=dict(bar="baz")))["foo"]["bar"] == "baz"
assert DottedDict(dict(foo=dict(bar="baz")))["foo.bar"] == "baz"
assert DottedDict(dict(foo=dict(bar="baz"))).get("lorem.ipsum", None) is None
assert DottedDict(dict(foo=dict(bar="baz"))).get("lorem.ipsum", "default") == "default"
根据Yoav的回答,一个更安全的方法是:
def deep_get(dictionary, *keys):
return reduce(lambda d, key: d.get(key, None) if isinstance(d, dict) else None, keys, dictionary)
减少方法的改进很少,使其与列表一起工作。也使用数据路径作为字符串除以点,而不是数组。
def deep_get(dictionary, path):
keys = path.split('.')
return reduce(lambda d, key: d[int(key)] if isinstance(d, list) else d.get(key) if d else None, keys, dictionary)