Home > Blockchain >  Python: Handle Missing Object keys in mapping and continue instructions
Python: Handle Missing Object keys in mapping and continue instructions

Time:10-29

I'm fairly new to Python so bear with me please. I have a function that takes two parameters, an api response and an output object, i need to assign some values from the api response to the output object:

def map_data(output, response):
    try:
        output['car']['name'] = response['name']
        output['car']['color'] = response['color']
        output['car']['date'] = response['date']
        #other mapping
        .
        . 
        .
        .
        #other mapping
     except KeyError as e:
        logging.error("Key Missing in api Response:  %s", str(e))
        pass

     return output

Now sometimes, the api response is missing some keys i'm using to generate my output object, so i used the KeyError exception to handle this case.

Now my question is, in a case where the 'color' key is missing from the api response, how can i catch the exception and continue to the line after it output['car']['date'] = response['date'] and the rest of the instructions.

i tried the pass instruction but it didn't have any affect.

Ps: i know i can check the existence of the key using:

if response.get('color') is not None: 
 output['car']['color'] = response['color']      

and then assign the values but seeing that i have about 30 values i need to map, is there any other way i can implement ? Thank you

CodePudding user response:

A few immediate ideas

(FYI - I'm not going to explain everything in detail - you can check out the python docs for more info, examples etc - that will help you learn more, rather than trying to explain everything here)

  1. Google 'python handling dict missing keys' for a million methods/ideas/approaches - it's a common use case!

  2. Convert your response dict to a defaultdict. In that case you can have a default value returned (eg None, '', 'N/A' ...whatever you like) if there is no actual value returned.

In this case you could do away with the try and every line would be executed.

from collections import defaultdict
resp=defaultdict(lambda: 'NA', response)
output['car']['date'] = response['date']  # will have value 'NA' if 'date' isnt in response
  1. Use the in syntax, perhaps in combination with a ternary else
output['car']['color'] = response['color'] if 'color' in response
output['car']['date'] = response['date'] if 'date' in response else 'NA'

Again you can do away with the try block and every line will execute.

  1. Use the dictionary get function, which allows you to specify a default if there is no value for that key:
output['car']['color'] = response.get('car', 'no car specified')

CodePudding user response:

You can create a utility function that gets the value from the response and if the value is not found, it returns an empty string. See example below:

def get_value_from_response_or_null(response, key):
    try:
        value = response[key]
        return value
    except KeyError as e:
        logging.error("Key Missing in api Response:  %s", str(e))
        return ""


def map_data(output, response):
    output['car']['name'] = get_value_from_response_or_null(response, 'name')
    output['car']['color'] = get_value_from_response_or_null(response, 'color')
    output['car']['date'] = get_value_from_response_or_null(response, 'date')
    # other mapping

    # other mapping

    return output

  • Related