Reputation: 126
I have a query parameter structure similar to this one:
data = {
"data1":"<enc_ssid_charger>",
"data2": {
"primary": {
"a": {
"a1": "a1",
"a2": "a2",
"a3": "a3"}},
"secondary": {
"b": {
"b1": "b1",
"b2": "b2"}}}}
The thing is that, primary and secondary can have one of these values: a, b, c or d (and the associated characteristics). Primary and secondary cannot have the same value, and secondary may not exist. Depending on the key inside primary or secondary I want to do a data validation but efficiently, without having to repeat code. Because now that's what happens:
if data['data2']['primary'].get('a', {}):
# data verification on data['data2']['primary']['a']['a1']
# data verification on data['data2']['primary']['a']['a2']
# data verification on data['data2']['primary']['a']['a3']
elif data['data2']['primary'].get('b', {}):
# data verification on data['data2']['primary']['b']['b1']
# data verification on data['data2']['primary']['b']['b2']
elif data['data2'].get('secondary',{}).get('a', {}):
# data verification on data['data2']['secondary']['a']['a1']
# data verification on data['data2']['secondary']['a']['a2']
...
elif data['data2'].get('secondary',{}).get('b', {}):
# data verification on data['data2']['secondary']['b']['b1']
...
My question is: how to make only 4 conditions for data verification (a, b, c and d) just changing the json reference and work for when secondary doesn't exist? (E.g. verify that data['data2']['xxxx']['a']['a1'] > 10 or data['data2']['xxxx']['b']['b2'] = 'hello', where xxxx can be either primary or seconday)
I would appreciate any kind of help, as having structured and clean code is very important to me. And in this case, I'm not sure how not to make it redound.
Solution found: Get absolute path of a key from nested dictionary in Python
Upvotes: 1
Views: 89
Reputation: 71461
You can condense your if-elif
statements further using dict.get
:
if (value:=data['data2']['primary'].get('a', data['data2']['primary'].get('b', {}))):
pass
elif (value:=data['data2']['secondary'].get('a', data['data2']['primary'].get('b', {}))):
pass
Another way, using Python's pattern matching syntax from 3.10
match data:
case {'data2':{'primary':{'a':value} | {'b':value}}}: print(value)
case {'data2':{'secondary':{'a':value} | {'b':value}}}: print(value)
Output:
{'a1': 'a1', 'a2': 'a2', 'a3': 'a3'}
Upvotes: 1
Reputation: 33335
Assuming you don't specifically care whether the key is a
or b
, you can iterate over the dict and grab whatever key is present:
for key in data['data2']['primary']:
# verify data['data2']['primary'][key]
if 'secondary' in data['data2']:
for key in data['data2']['secondary']:
# verify data['data2']['secondary'][key]
Upvotes: 1