1

I can have the following JSON string:

{ "response" : [ [ { "name" : "LA_",
          "uid" : 123456
        } ],
      [ { "cid" : "1",
          "name" : "Something"
        } ],
      [ { "cid" : 1,
          "name" : "Something-else"
        } ]
    ] }

or one of the following:

{"error":"some-error"}

{ "response" : [ [ { "name" : "LA_",
          "uid" : 123456
        } ],
      [ { "cid" : "1",
          "name" : ""
        } ],
      [ { "cid" : 1,
          "name" : "Something-else"
        } ]
    ] }

{ "response" : [ [ { "name" : "LA_",
          "uid" : 123456
        } ] ] }

So, I am not sure if all childs and elements are there. Will it be enough to do the following verifications to get Something value:

if jsonstr.get('response'):
    jsonstr = jsonstr.get('response')[1][0]
    if jsonstr:
        name = jsonstr.get('name')
        if jsonstr: # I don't need empty value
            # save in the database

Can the same be simplified?

1 Answer 1

2

You're not guaranteed that the ordering of your inner objects will be the same every time you parse it, so indexing is not a safe bet to reference the index of the object with the name attribute set to Something.

Instead of nesting all those if statements, you can get away with using a list comprehension. Observe that if you iterate the response key, you get a list of lists, each with a dictionary inside of it:

>>> data = {"response":[[{"uid":123456,"name":"LA_"}],[{"cid":"1","name":"Something"}],[{"cid":1,"name":"Something-else"}]]}
>>> [lst for lst in data.get('response')]
[[{'name': 'LA_', 'uid': 123456}], [{'name': 'Something', 'cid': '1'}], [{'name': 'Something-else', 'cid': 1}]]

If you index the first item in each list (lst[0]), you end up with a list of objects:

>>> [lst[0] for lst in data.get('response')]
[{'name': 'LA_', 'uid': 123456}, {'name': 'Something', 'cid': '1'}, {'name': 'Something-else', 'cid': 1}]

If you then add an if condition into your list comprehension to match the name attribute on the objects, you get a list with a single item containing your desired object:

>>> [lst[0] for lst in data.get('response') if lst[0].get('name') == 'Something']
[{'name': 'Something', 'cid': '1'}]

And then by indexing the first item that final list, you get the desired object:

>>> [lst[0] for lst in data.get('response') if lst[0].get('name') == 'Something'][0]
{'name': 'Something', 'cid': '1'}

So then you can just turn that into a function and move on with your life:

def get_obj_by_name(data, name):
    objects = [lst[0] for lst in data.get('response', []) if lst[0].get('name') == name]
    if objects:
        return objects[0]

    return None

print get_obj_by_name(data, 'Something')
# => {'name': 'Something', 'cid': '1'}

print get_obj_by_name(data, 'Something')['name']
# => 'Something'

And it should be resilient and return None if the response key isn't found:

print get_obj_by_name({"error":"some-error"}, 'Something')
# => None
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, @jathanism, for so detailed answer. Actually, 'Something' is the value I am looking for - it can be any other value. 3rd party side doesn't provide me with any identifier of this element, so I have to rely on their sequence.

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.