Python get vaule conditional instead of if else

Viewed 47

I'm in the following situation:

title_value = clean_result['format']['tags'].get('title')

... sometimes title is pure uppercase. Can I handle this more efficiently than using the if-else clause here?

Something like this:

title_value = clean_result['format']['tags'].get('title', 'TITLE')
5 Answers

The optional second parameter to the get method on a dictionary is a default value to return if the key doesn't exist. You could do something like this

tags = clean_result['format']['tags']
title_value = tags.get('title', tags.get('TITLE'))

Unfortunately, when the item in the data is not case sensitive, this can get a bit more messy. This is because not knowing the key makes things a bit more difficult. You could try something like this:

tags = clean_result.get('format',{}).get('tags',{})
title_value = tags.get('title',tags.get('TITLE'))

Notice the use of .get for all levels in the dictionary with a default value of {}. This allows you to avoid an exception if the sub dictionary structure is missing at any point. You would want to remove this if for some reason you wanted to raise an exception in your code when data was incorrect.

Alternatively, you could try something like renaming all keys to lowercase values and fetching the item from that.

title_value = {key.lower():value for key, value in clean_result.get('format',{}).get('tags',{}).items()}.get('title')

Let's simplify the example. We have two different dictionaries with similar keys:

d1 = { 'title': 'Title 1' }
d2 = { 'TITLE': 'Title 2' }

Now we want to use these in some function to access the "title" in a consistent way:

foo(d1)
foo(d2)

One solution is to just transform the keys to all lower case:

def foo(d):
  new_d = {k.lower(): v for k, v in d.items() }
  print(new_d['title'])

Note how I removed some details from your original code example. Your question is only about a dictionary. It doesn't matter that the dict is named clean_result, nor does it matter that this dictionary is nested inside a larger data structure where you have to index to get to it.

The function is the following:

dict.get(key[, default])

Where default is what the function will return if the key is not found.

Which means that you can do the following:

title_value = clean_result['format']['tags'].get('title', clean_result['format']['tags'].get('TITLE'))

I've now managed to first cleanup the json before writing it to disk:

            n = {}
            for k, v in write_result['format']['tags'].items():
                n[k.lower()] = v
                write_result['format']['tags'] = n

Which again solves all issues here, even if there are more than one element lowercase

Related