How to index a json key array that sometimes only has one element, and is no longer an iterable?

Question:

I’m new to json, and I’m having trouble dealing with indexing keys that usually have sub-array but sometimes they don’t.

Usually, key2 and key3 contain sub-array:

json_obj = json.loads(x)

json_obj["key1"]["key2"][idx]["key3"][idx]["key4"]

However, sometimes key2 and/or key3 is no longer an array
executing above code would throw an exception

to retrieve key4:

json_obj["key1"]["key2"]["key3"][idx]["key4"]
json_obj["key1"]["key2"][idx]["key3"]["key4"]
json_obj["key1"]["key2"]["key3"]["key4"]

Is there an elegant way to retrieve key4 regardless the condition of key2 and key3?

Asked By: 7E10FC9A

||

Answers:

All you need to do is transverse the tree, getting the next key if the value is a dictionary or getting an index if the value is a list. Here is a function to do that general behavior:

def getKey(data, path, indices):
    el = data
    # keep transversing until we find a primitive value
    while type(el) is dict or type(el) is list:
        if type(el) is list:
            # if el is a list, try using one of the indicies passed
            el = el[indices.pop()]
        else:
            # otherwsie, go along the path specified
            el = el[path.pop(0)]
    return el

Note that list.pop() removes an element from a list, then returns the element it removed. So, el[indices.pop()] removes an index from indices, then indexes el with that index (see the documentation for more).

This function takes three parameters, the dictionary to transverse, a list of keys, and a list of indices to use. Indicies will be taken off the beginning of indices. In your specific case, you can call it like this:

getKey(json_obj, ['key1', 'key2', 'key3', 'key4'], [idx, idx]);
Answered By: Michael M.
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.