我有一本嵌套的字典。是否只有一种方法可以安全地传递价值观?
try:
example_dict['key1']['key2']
except KeyError:
pass
或者python有一个类似get()的方法用于嵌套字典?
我有一本嵌套的字典。是否只有一种方法可以安全地传递价值观?
try:
example_dict['key1']['key2']
except KeyError:
pass
或者python有一个类似get()的方法用于嵌套字典?
当前回答
Glom是一个很好的库,可以进入点查询:
In [1]: from glom import glom
In [2]: data = {'a': {'b': {'c': 'd'}}}
In [3]: glom(data, "a.b.c")
Out[3]: 'd'
查询失败有一个很好的堆栈跟踪,指出确切的故障点:
In [4]: glom(data, "a.b.foo")
---------------------------------------------------------------------------
PathAccessError Traceback (most recent call last)
<ipython-input-4-2a3467493ac4> in <module>
----> 1 glom(data, "a.b.foo")
~/.cache/pypoetry/virtualenvs/neural-knapsack-dE7ihQtM-py3.8/lib/python3.8/site-packages/glom/core.py in glom(target, spec, **kwargs)
2179
2180 if err:
-> 2181 raise err
2182 return ret
2183
PathAccessError: error raised while processing, details below.
Target-spec trace (most recent last):
- Target: {'a': {'b': {'c': 'd'}}}
- Spec: 'a.b.foo'
glom.core.PathAccessError: could not access 'foo', part 2 of Path('a', 'b', 'foo'), got error: KeyError('foo')
默认保护:
In [5]: glom(data, "a.b.foo", default="spam")
Out[5]: 'spam'
格洛姆的魅力在于多功能的规格参数。例如,可以很容易地从以下数据中提取所有的名字:
In [8]: data = {
...: "people": [
...: {"first_name": "Alice", "last_name": "Adams"},
...: {"first_name": "Bob", "last_name": "Barker"}
...: ]
...: }
In [9]: glom(data, ("people", ["first_name"]))
Out[9]: ['Alice', 'Bob']
更多的例子请阅读glom文档。
其他回答
我的实现下降到子字典,忽略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 : json to extract value from if exists
path : details.detail.first_name
empty path represents root
returns a tuple (boolean, object)
boolean : True if path exists, otherwise False
object : the object if path exists otherwise None
'''
def get_json_value_at_path(json, path=None, default=None):
if not bool(path):
return True, json
if type(json) is not dict :
raise ValueError(f'json={json}, path={path} not supported, json must be a dict')
if type(path) is not str and type(path) is not list:
raise ValueError(f'path format {path} not supported, path can be a list of strings like [x,y,z] or a string like x.y.z')
if type(path) is str:
path = path.strip('.').split('.')
key = path[0]
if key in json.keys():
return get_json_value_at_path(json[key], path[1:], default)
else:
return False, default
使用示例:
my_json = {'details' : {'first_name' : 'holla', 'last_name' : 'holla'}}
print(get_json_value_at_path(my_json, 'details.first_name', ''))
print(get_json_value_at_path(my_json, 'details.phone', ''))
(真的,大声叫) (假的,”)
对于嵌套的字典/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
Glom是一个很好的库,可以进入点查询:
In [1]: from glom import glom
In [2]: data = {'a': {'b': {'c': 'd'}}}
In [3]: glom(data, "a.b.c")
Out[3]: 'd'
查询失败有一个很好的堆栈跟踪,指出确切的故障点:
In [4]: glom(data, "a.b.foo")
---------------------------------------------------------------------------
PathAccessError Traceback (most recent call last)
<ipython-input-4-2a3467493ac4> in <module>
----> 1 glom(data, "a.b.foo")
~/.cache/pypoetry/virtualenvs/neural-knapsack-dE7ihQtM-py3.8/lib/python3.8/site-packages/glom/core.py in glom(target, spec, **kwargs)
2179
2180 if err:
-> 2181 raise err
2182 return ret
2183
PathAccessError: error raised while processing, details below.
Target-spec trace (most recent last):
- Target: {'a': {'b': {'c': 'd'}}}
- Spec: 'a.b.foo'
glom.core.PathAccessError: could not access 'foo', part 2 of Path('a', 'b', 'foo'), got error: KeyError('foo')
默认保护:
In [5]: glom(data, "a.b.foo", default="spam")
Out[5]: 'spam'
格洛姆的魅力在于多功能的规格参数。例如,可以很容易地从以下数据中提取所有的名字:
In [8]: data = {
...: "people": [
...: {"first_name": "Alice", "last_name": "Adams"},
...: {"first_name": "Bob", "last_name": "Barker"}
...: ]
...: }
In [9]: glom(data, ("people", ["first_name"]))
Out[9]: ['Alice', 'Bob']
更多的例子请阅读glom文档。
递归法(мб п п и и одитс)
示例dict类型:
foo = [{'feature_name': 'Sample Creator > Contract Details > Elements of the page',
'scenarios': [{'scenario_name': 'SC, CD, Elements of the page',
'scenario_status': 'failed',
'scenario_tags': None,
'steps': [{'duration': 0,
'name': 'I open application Stage and login by '
'SPT_LOGIN and password SPT_PWD',
'status': 'untested'},
{'duration': 0,
'name': 'I open Sample Creator query page',
'status': 'untested'},
{'duration': 7.78166389465332,
'name': 'I open application Stage and login by '
'SPT_LOGIN and password SPT_PWD',
'status': 'passed'},
{'duration': 3.985326051712036,
'name': 'I open Sample Creator query page',
'status': 'passed'},
{'duration': 2.9063704013824463,
'name': 'Enter value: '
'X-2008-CON-007,X-2011-CON-016 in '
'textarea: project_text_area sleep: 1',
'status': 'passed'},
{'duration': 4.4447715282440186,
'name': 'I press on GET DATA',
'status': 'passed'},
{'duration': 1.1209557056427002,
'name': 'Verify the top table on Contract Details',
'status': 'passed'},
{'duration': 3.8173601627349854,
'name': 'I export contract_details table by offset '
'x:100, y:150',
'status': 'passed'},
{'duration': 1.032956600189209,
'name': 'Check data of '
'sc__cd_elements_of_the_page_1 and skip '
'cols None',
'status': 'passed'},
{'duration': 0.04593634605407715,
'name': "Verify 'Number of Substances' column "
'values',
'status': 'passed'},
{'duration': 0.10199904441833496,
'name': 'Substance Sample Details bottom table '
'columns',
'status': 'passed'},
{'duration': 0.0009999275207519531,
'name': 'Verify the Substance Sample Details '
'bottom table',
'status': 'passed'},
{'duration': 3.8558616638183594,
'name': 'I export substance_sample_details table '
'by offset x:100, y:150',
'status': 'passed'},
{'duration': 1.0329277515411377,
'name': 'Check data of '
'sc__cd_elements_of_the_page_2 and skip '
'cols None',
'status': 'passed'},
{'duration': 0.2879970073699951,
'name': 'Click on AG-13369',
'status': 'passed'},
{'duration': 3.800830364227295,
'name': 'I export substance_sample_details table '
'by offset x:100, y:150',
'status': 'passed'},
{'duration': 1.0169551372528076,
'name': 'Check data of '
'sc__cd_elements_of_the_page_3 and skip '
'cols None',
'status': 'passed'},
{'duration': 1.7484464645385742,
'name': 'Select all cells, table: 2',
'status': 'passed'},
{'duration': 3.812828779220581,
'name': 'I export substance_sample_details table '
'by offset x:100, y:150',
'status': 'passed'},
{'duration': 1.0029594898223877,
'name': 'Check data of '
'sc__cd_elements_of_the_page_2 and skip '
'cols None',
'status': 'passed'},
{'duration': 1.6729373931884766,
'name': 'Set window size x:800, y:600',
'status': 'passed'},
{'duration': 30.145705699920654,
'name': 'All scrollers are placed on top 6 and far '
'left 8',
'status': 'failed'}]}]},
{'feature_name': 'Sample Creator > Substance Sample History > Elements of the '
'page',
'scenarios': [{'scenario_name': 'SC, SSH, Elements of the page',
'scenario_status': 'passed',
'scenario_tags': None,
'steps': [{'duration': 0,
'name': 'I open application Stage and login by '
'SPT_LOGIN and password SPT_PWD',
'status': 'untested'},
{'duration': 0,
'name': 'I open Sample Creator query page',
'status': 'untested'},
{'duration': 7.305850505828857,
'name': 'I open application Stage and login by '
'SPT_LOGIN and password SPT_PWD',
'status': 'passed'},
{'duration': 3.500955104827881,
'name': 'I open Sample Creator query page',
'status': 'passed'},
{'duration': 3.0419492721557617,
'name': 'Enter value: NOA401800 SYN-NOA '
'A,S4A482070C SYN-ISN-OLD '
'O,S04A482167T,S04A482190Y,CSAA796564,CSCD106701 '
'in textarea: id_text_area sleep: 1',
'status': 'passed'},
{'duration': 49.567158460617065,
'name': 'I press on GET DATA',
'status': 'passed'},
{'duration': 0.13904356956481934,
'name': 'Open substance_sample_history',
'status': 'passed'},
{'duration': 1.1039845943450928,
'name': 'Columns displayed',
'status': 'passed'},
{'duration': 3.881945848464966,
'name': 'I export export_parent_table table by '
'offset x:100, y:150',
'status': 'passed'},
{'duration': 1.0334820747375488,
'name': 'Check data of '
'sc__ssh_elements_of_the_page_1 and skip '
'cols None',
'status': 'passed'},
{'duration': 0.0319981575012207,
'name': "Title is 'Additional Details for Marked "
"Rows'",
'status': 'passed'},
{'duration': 0.08897256851196289,
'name': 'Columns displayed (the same as in top '
'table)',
'status': 'passed'},
{'duration': 25.192569971084595,
'name': 'Verify the content of the bottom table',
'status': 'passed'},
{'duration': 4.308935880661011,
'name': 'I export '
'additional_details_for_marked_rows table '
'by offset x:100, y:150',
'status': 'passed'},
{'duration': 1.0089836120605469,
'name': 'Check data of '
'sc__ssh_elements_of_the_page_1 and skip '
'cols None',
'status': 'passed'}]}]}]
代码:
def get_keys(_dict: dict, prefix: list):
prefix += list(_dict.keys())
return prefix
def _loop_elements(elems:list, prefix=None, limit=None):
prefix = prefix or []
limit = limit or 9
try:
if len(elems) != 0 and isinstance(elems, list):
for _ in elems:
if isinstance(_, dict):
get_keys(_, prefix)
for item in _.values():
_loop_elements(item, prefix, limit)
return prefix[:limit]
except TypeError:
return
>>>goo = _loop_elements(foo,limit=9)
>>>goo
['feature_name', 'scenarios', 'scenario_name', 'scenario_status', 'scenario_tags', 'steps', 'duration', 'name', 'status']