1

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

2 Answers 2

1

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]
Sign up to request clarification or add additional context in comments.

4 Comments

The question was precisely because I do need a and b :)))
I added an example to the question, if you can help me, I would appreciate it
@Bemojo It's still not clear exactly what you need to know about the data. For example if primary contains a versus b, how would the validation differ?
If one time primary has a and next time it's secondary, I would like to validate in the same code block data['data2']['xxxx']['a']['a1'], where xxxx is either primary or secondary. The problem is to identify the json path to get the variable to use
1

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

5 Comments

Thank you for the help! However, for the 1st solution I'm getting SyntaxError because of := and the 2nd solution will not work because I'm running python 2.7.17... Do you have a 3rd solution? :))
In the 1st solution will I be able to verify that a > 10? Without having to write data['data2']['primary']['a']['a1'] or data['data2']['secondary']['a']['a1'], but something like data['data2']['xxxxx']['a']['a1']?
I added an example to the question, if you can help me, I would appreciate it
@Bemojo The solutions require python versions > 3.8 (3.9 for :=, and 3.10 for the match-case). You do not need := for the first solution, simply write data['data2']['primary'].get('a', data['data2']['primary'].get('b', {})) again in the body of the conditional, where you can run a check for the value being greater than 10.
But after how can I know if it is data['data2']['primary']['a'] or data['data2']['primary']['b'] with your solution? The problem is to identify the json path to get the variable to use

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.