drgxfs
drgxfs

Reputation: 1127

How to improve repeated use of a try statement in Python?

I am trying to extract several elements from a JSON object which contains metadata about a song, using Python. To test if information is available, I am using a try statement for each metadata element. Also, for some string processing that I need to do later in my program, I am saving each value in a different variable.

Any suggestions on how to improve the following code in order to not make a try/except statement for each different metadata value?

if len(r['response']['songs']) is not 0:
    # Request information about the artist
    artist_desc_string = "http://developer.echonest.com/api/v4/artist/terms?api_key="+api_key+\
                         "&name="+artist+"&format=json"
    r2 = requests.get(artist_desc_string).json()

    # Extract information from the song JSON
    try:
        title = r['response']['songs'][0]['title']
    except (IndexError, KeyError):
        title = "NULL"

    try:
        artist_name = r['response']['songs'][0]['artist_name']
    except (IndexError, KeyError):
        artist_name = "NULL"

    try:
        artist_location = r['response']['songs'][0]['artist_location']['location'].replace(',','*')
    except (IndexError, KeyError):
        artist_location = "NULL"

    try:
    ...
    ...

Upvotes: 2

Views: 140

Answers (3)

Aamir Rind
Aamir Rind

Reputation: 39659

Maybe this could help:

def get_value(d, keys):
    try:
        if keys:
            for i in range(len(keys)):
                key = keys[i]
                return get_value(d[key], keys[i+1:])
        return d
    except (IndexError, KeyError):
        return "Null"


>>> d = {'person': {'name': {'first': 'aamir'}}}
>>> get_value(d, ['person', 'name', 'first'])
aamir

Upvotes: 3

Joran Beasley
Joran Beasley

Reputation: 113988

something like this maybe?

def get_or_dont(d,list_of_keys):
    d2 = d
    while list_of_keys:
        try:
            d2 = d2[list_of_keys.pop(0)]
            if not list_of_keys: return d2
        except:
            break
    return "Null"

r = {'response':{
'a':5,
'b':{'6':{'5':3}},
'c':[1,2,3]
}}
print get_or_dont(r['response'],["b","6"])

Upvotes: 3

drez90
drez90

Reputation: 814

Use a for loop with all possible attributes...

attribs = {'title': None, 'artist_name':None, 'location': None, 'etc': None} for key in attribs: try: attribs[key] = r['response']['songs'][0][key] except (IndexError, KeyError): attribs[key] = "NULL"

That way you only have to manage the dict attribs ...

As far as grabbing unexpected attributes, you could always get the keys of the JSON object and create more entries in attribs

Upvotes: 1

Related Questions