중첩된 사전의 값을 가져오는 안전한 방법
나는 중첩된 사전을 가지고 있다.안전하게 가치를 전달할 수 있는 방법은 하나뿐입니까?
try:
example_dict['key1']['key2']
except KeyError:
pass
은 비단뱀과 같은 .get()
스트트 사? ???
하면 .get
2회:
example_dict.get('key1', {}).get('key2')
하면 반환됩니다.None
쪽인가 하면key1
★★★★★★★★★★★★★★★★★」key2
을 사용하다
에도 「」, 「」, 「」가 .AttributeError
example_dict['key1']
하지만 dict dict(dict)가 있는 (dict)와 )는 .get
「 」try..except
이 올린 가 'Code'를 됩니다.TypeError
instead의 경우example_dict['key1']
스크립트 할 수 없습니다.
다른 은 ''라는 것입니다.try...except
첫 번째 키가 없어진 직후에 쇼트 포인트로 표시됩니다.★★★의 get
을 사용하다
「」를 참조해 주세요.example_dict['key1']['key2']
KeyErrors가 발생하지 않도록 하기 위해 Hasher 레시피를 사용할 수 있습니다.
class Hasher(dict):
# https://stackoverflow.com/a/3405143/190597
def __missing__(self, key):
value = self[key] = type(self)()
return value
example_dict = Hasher()
print(example_dict['key1'])
# {}
print(example_dict['key1']['key2'])
# {}
print(type(example_dict['key1']['key2']))
# <class '__main__.Hasher'>
키가 없어지면 빈 해셔가 반환되는 것에 주의해 주세요.
★★Hasher
는 의 입니다.dict
를 사용할 할 수 .dict
수 . 키를 할 뿐입니다. 동일한 메서드와 구문을 모두 사용할 수 있습니다. 해셔스
할 수 .dict
Hasher
음음음같 뭇매하다
hasher = Hasher(example_dict)
Hasher
dict
마찬가지로 간단합니다.
regular_dict = dict(hasher)
또 다른 방법은 도우미 기능의 추함을 숨기는 것입니다.
def safeget(dct, *keys):
for key in keys:
try:
dct = dct[key]
except KeyError:
return None
return dct
따라서 나머지 코드는 비교적 읽을 수 있습니다.
safeget(example_dict, 'key1', 'key2')
python reduce를 사용할 수도 있습니다.
def deep_get(dictionary, *keys):
return reduce(lambda d, key: d.get(key) if d else None, keys, dictionary)
여기에 있는 모든 답변과 제가 한 작은 변경 사항을 조합하면 이 기능은 유용하다고 생각합니다.안전하고, 빠르고, 유지보수가 용이합니다.
def deep_get(dictionary, keys, default=None):
return reduce(lambda d, key: d.get(key, default) if isinstance(d, dict) else default, keys.split("."), dictionary)
예:
from functools import reduce
def deep_get(dictionary, keys, default=None):
return reduce(lambda d, key: d.get(key, default) if isinstance(d, dict) else default, keys.split("."), dictionary)
person = {'person':{'name':{'first':'John'}}}
print(deep_get(person, "person.name.first")) # John
print(deep_get(person, "person.name.lastname")) # None
print(deep_get(person, "person.name.lastname", default="No lastname")) # No lastname
첫 번째 단계에서 빈 사전을 얻을 수 있습니다.
example_dict.get('key1',{}).get('key2')
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(d, keys):
if not keys or d is None:
return d
return deep_get(d.get(keys[0]), keys[1:])
예
d = {'meta': {'status': 'OK', 'status_code': 200}}
deep_get(d, ['meta', 'status_code']) # => 200
deep_get(d, ['garbage', 'status_code']) # => None
보다 세련된 버전
def deep_get(d, keys, default=None):
"""
Example:
d = {'meta': {'status': 'OK', 'status_code': 200}}
deep_get(d, ['meta', 'status_code']) # => 200
deep_get(d, ['garbage', 'status_code']) # => None
deep_get(d, ['meta', 'garbage'], default='-') # => '-'
"""
assert type(keys) is list
if d is None:
return default
if not keys:
return d
return deep_get(d.get(keys[0]), keys[1:], default)
한 번 .python-benedict
.
은 것은다이 it it이다.dict
키 경로 지원 등을 제공하는 서브 클래스입니다.
치::pip install python-benedict
from benedict import benedict
example_dict = benedict(example_dict, keypath_separator='.')
이제 키 경로를 사용하여 중첩된 값에 액세스할 수 있습니다.
val = example_dict['key1.key2']
# using 'get' method to avoid a possible KeyError:
val = example_dict.get('key1.key2')
또는 키 목록을 사용하여 중첩된 값에 액세스합니다.
val = example_dict['key1', 'key2']
# using get to avoid a possible KeyError:
val = example_dict.get(['key1', 'key2'])
GitHub에서 잘 테스트되고 오픈 소스입니다.
https://github.com/fabiocaccamo/python-benedict
주의: 이 프로젝트의 작성자입니다.
리덕션 어프로치는 깔끔하고 짧지만, 단순한 루프가 더 보기 쉽다고 생각합니다.기본 매개 변수도 포함했습니다.
def deep_get(_dict, keys, default=None):
for key in keys:
if isinstance(_dict, dict):
_dict = _dict.get(key, default)
else:
return default
return _dict
리덕션 원라이너의 구조를 이해하기 위한 연습으로 다음과 같이 했습니다.하지만 궁극적으로 루프 접근법이 더 직관적으로 보입니다.
def deep_get(_dict, keys, default=None):
def _reducer(d, key):
if isinstance(d, dict):
return d.get(key, default)
return default
return reduce(_reducer, keys, _dict)
사용.
nested = {'a': {'b': {'c': 42}}}
print deep_get(nested, ['a', 'b'])
print deep_get(nested, ['a', 'b', 'z', 'z'], default='missing')
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')
default
:
In [5]: glom(data, "a.b.foo", default="spam")
Out[5]: 'spam'
★★★의 glom
parameterspec spec에 있습니다.를 들어,의 이름에서 할 수 .data
:
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']
자세한 예는 문서를 참조해 주세요.
pydash를 사용할 수 있습니다.
import pydash as _ #NOTE require `pip install pydash`
_.get(example_dict, 'key1.key2', default='Default')
https://pydash.readthedocs.io/en/latest/api.html
dict를 랩하여 키에 따라 검색할 수 있는 간단한 클래스:
class FindKey(dict):
def get(self, path, default=None):
keys = path.split(".")
val = None
for key in keys:
if val:
if isinstance(val, list):
val = [v.get(key, default) if v else None for v in val]
else:
val = val.get(key, default)
else:
val = dict.get(self, key, default)
if not val:
break
return val
예를 들어 다음과 같습니다.
person = {'person':{'name':{'first':'John'}}}
FindDict(person).get('person.name.first') # == 'John'
키가 됩니다.None
. 이렇게 해서 수 요.default=
를 누르다FindDict
":":": " ": ":":
FindDict(person, default='').get('person.name.last') # == doesn't exist, so ''
저는 GenesRus와 unutbu의 답변을 매우 간단하게 수정했습니다.
class new_dict(dict):
def deep_get(self, *args, default=None):
_empty_dict = {}
out = self
for key in args:
out = out.get(key, _empty_dict)
return out if out else default
다음과 같이 동작합니다.
d = new_dict(some_data)
d.deep_get("key1", "key2", "key3", ..., default=some_value)
두 번째 레벨 키를 취득할 경우 다음 작업을 수행할 수 있습니다.
key2_value = (example_dict.get('key1') or {}).get('key2')
3.부터는 Python 3.4를 사용할 수 .부터는with suppress (KeyError)
Key 하지 않고 json 합니다.
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']
테크드래곤 제공.상세한 것에 대하여는, https://stackoverflow.com/a/45874251/1189659 를 참조해 주세요.
속성의 깊이를 얻기 위해 이것을 보고 안전하게 네스트하기 위해 다음과 같이 만들었습니다.dict
도트 표기법을 사용하여 값을 지정합니다.이게 나한테 효과가 있는 이유는dicts
MongoDB 있기 키에 MongoDB가 있지 ..
제에서는, s., 「」, 「」, 「」, 「」)를 할 수 .None
데이터에는 없기 때문에 함수를 호출할 때 try/except 패턴을 피할 수 있습니다.
from functools import reduce # Python 3
def deepgetitem(obj, item, fallback=None):
"""Steps through an item chain to get the ultimate value.
If ultimate value or path to value does not exist, does not raise
an exception and instead returns `fallback`.
>>> d = {'snl_final': {'about': {'_icsd': {'icsd_id': 1}}}}
>>> deepgetitem(d, 'snl_final.about._icsd.icsd_id')
1
>>> deepgetitem(d, 'snl_final.about._sandbox.sbx_id')
>>>
"""
def getitem(obj, name):
try:
return obj[name]
except (KeyError, TypeError):
return fallback
return reduce(getitem, item.split('.'), obj)
그러나 같은 것에 대한 다른 함수도 키가 발견되었는지 여부를 나타내는 부울을 반환하고 예기치 않은 오류를 처리합니다.
'''
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', ''))
(참, 'holla')
(거짓, ')
이미 많은 좋은 답변들이 있지만, 나는 자바스크립트 랜드의 lodash get과 유사한 기능을 생각해냈다.이 기능은 인덱스별 목록에도 접근할 수 있다.
def get(value, keys, default_value = None):
'''
Useful for reaching into nested JSON like data
Inspired by JavaScript lodash get and Clojure get-in etc.
'''
if value is None or keys is None:
return None
path = keys.split('.') if isinstance(keys, str) else keys
result = value
def valid_index(key):
return re.match('^([1-9][0-9]*|[0-9])$', key) and int(key) >= 0
def is_dict_like(v):
return hasattr(v, '__getitem__') and hasattr(v, '__contains__')
for key in path:
if isinstance(result, list) and valid_index(key) and int(key) < len(result):
result = result[int(key)] if int(key) < len(result) else None
elif is_dict_like(result) and key in result:
result = result[key]
else:
result = default_value
break
return result
def test_get():
assert get(None, ['foo']) == None
assert get({'foo': 1}, None) == None
assert get(None, None) == None
assert get({'foo': 1}, []) == {'foo': 1}
assert get({'foo': 1}, ['foo']) == 1
assert get({'foo': 1}, ['bar']) == None
assert get({'foo': 1}, ['bar'], 'the default') == 'the default'
assert get({'foo': {'bar': 'hello'}}, ['foo', 'bar']) == 'hello'
assert get({'foo': {'bar': 'hello'}}, 'foo.bar') == 'hello'
assert get({'foo': [{'bar': 'hello'}]}, 'foo.0.bar') == 'hello'
assert get({'foo': [{'bar': 'hello'}]}, 'foo.1') == None
assert get({'foo': [{'bar': 'hello'}]}, 'foo.1.bar') == None
assert get(['foo', 'bar'], '1') == 'bar'
assert get(['foo', 'bar'], '2') == None
솔루션에 다른 라이브러리를 사용하는 경우 이 방법이 가장 적합합니다.
https://github.com/maztohir/dict-path
from dict-path import DictPath
data_dict = {
"foo1": "bar1",
"foo2": "bar2",
"foo3": {
"foo4": "bar4",
"foo5": {
"foo6": "bar6",
"foo7": "bar7",
},
}
}
data_dict_path = DictPath(data_dict)
data_dict_path.get('key1/key2/key3')
다음은 unutbu의 함수 답변과 함께 다음과 같은 솔루션을 제공합니다.
- python 명명 가이드라인
- 파라미터로서의 기본값
- try를 사용하지 않고 키가 객체에 있는지 확인만 합니다.
def safe_get(dictionary, *keys, default=None):
for key in keys:
if key not in dictionary:
return default
dictionary = dictionary[key]
return dictionary
내 코드에서 유용하다고 생각한 unutbu의 답변을 각색한 것입니다.
example_dict.setdefaut('key1', {}).get('key2')
KeyError를 피하기 위해 key1에 해당 키가 아직 없는 경우 해당 딕셔너리 엔트리가 생성됩니다.저처럼 키쌍을 포함하는 중첩된 사전을 끝내려면 이 방법이 가장 쉬운 해결책인 것 같습니다.
키 중 하나가 누락된 경우 키 오류를 발생시키는 것은 합리적인 일이기 때문에 이를 확인하지 않고 단일 키를 얻을 수도 있습니다.
def get_dict(d, kl):
cur = d[kl[0]]
return get_dict(cur, kl[1:]) if len(kl) > 1 else cur
거의 개선되지 않았다reduce
목록과 함께 작동하도록 접근합니다.또한 데이터 경로를 배열 대신 점으로 나눈 문자열로 사용합니다.
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)
내가 사용한 솔루션은 double get과 비슷하지만 다른 로직을 사용하여 Type Error를 회피할 수 있는 추가 기능을 갖추고 있습니다.
value = example_dict['key1']['key2'] if example_dict.get('key1') and example_dict['key1'].get('key2') else default_value
그러나 사전이 중첩될수록 이 작업은 더 번거로워집니다.
중첩된 사전의 경우/JSON 룩업, 딕터를 사용할 수 있습니다.
pip install 딕터
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"
]
}
}
}
Lonestar 항목을 가져오려면 점으로 구분된 경로를 제공하십시오.
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
나는 이 대답을 거의 바꾸지 않았다.리스트와 숫자를 함께 사용하는지 체크하는 것도 추가했습니다.이제 어떤 식으로든 사용할 수 있습니다. deep_get(allTemp, [0], {})
또는deep_get(getMinimalTemp, [0, minimalTemperatureKey], 26)
기타
def deep_get(_dict, keys, default=None):
def _reducer(d, key):
if isinstance(d, dict):
return d.get(key, default)
if isinstance(d, list):
return d[key] if len(d) > 0 else default
return default
return reduce(_reducer, keys, _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']
def safeget(_dct, *_keys):
if not isinstance(_dct, dict): raise TypeError("Is not instance of dict")
def foo(dct, *keys):
if len(keys) == 0: return dct
elif not isinstance(_dct, dict): return None
else: return foo(dct.get(keys[0], None), *keys[1:])
return foo(_dct, *_keys)
assert safeget(dict()) == dict()
assert safeget(dict(), "test") == None
assert safeget(dict([["a", 1],["b", 2]]),"a", "d") == None
assert safeget(dict([["a", 1],["b", 2]]),"a") == 1
assert safeget({"a":{"b":{"c": 2}},"d":1}, "a", "b")["c"] == 2
당신이 원하는 대로 할 수 있는 패키지 deepxtract를 작성했습니다.https://github.com/ya332/deepextract 당신은 할 수 있습니다.
from deepextract import deepextract
# Demo: deepextract.extract_key(obj, key)
deeply_nested_dict = {
"items": {
"item": {
"id": {
"type": {
"donut": {
"name": {
"batters": {
"my_target_key": "my_target_value"
}
}
}
}
}
}
}
}
print(deepextract.extract_key(deeply_nested_dict, "my_target_key") == "my_target_value")
돌아온다
True
하위 명령어로 내려오는 구현은 무시합니다.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
도트를 사용할 수 있습니다.
pip install dotted
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"
언급URL : https://stackoverflow.com/questions/25833613/safe-method-to-get-value-of-nested-dictionary
'sourcecode' 카테고리의 다른 글
PHP에서 다차원 어레이를 단순 어레이로 "평탄화"하는 방법은 무엇입니까? (0) | 2023.01.30 |
---|---|
테스트 실패: Jest + Vue 3 + Vuex + Typescript: TypeError: 정의되지 않은 속성 'then'을 읽을 수 없습니다. (0) | 2023.01.30 |
Android 앱을 MySQL 데이터베이스에 연결하는 방법 (0) | 2023.01.20 |
POST 데이터를 Postman과 함께 Raw JSON을 통해 전송 (0) | 2023.01.20 |
방금 발생한 MySQL 경고를 표시하려면 어떻게 해야 합니까? (0) | 2023.01.20 |