Home > database >  Python 3.x: Error handling with lambda expression
Python 3.x: Error handling with lambda expression

Time:09-15

I am newbie to python and currently learning some mapping data types. Please forgive me if any irrelevant keywords are used.

There is list of dictionaries and need to perform some actions and need to return the results. Below solutions is working well but creates an issue in specific conditions -

>>> x = [{'a':10,'b':5},{'a':6,'b':4},{'a':5,'b':1}]
>>> list(map(lambda y: y['a']/y['b'], x))
[2.0, 1.5, 5.0]

Now there is a problems with dict x. It's an input coming from other sources (apis) and there is high possibilities of 2 scenarios -

  1. 0 can be come at place of b which throw ZeroDivisionError exception. Is there any to handle within lambda expression?

I tried with below options with if/else -

>>> x = [{'a':10,'b':5},{'a':6,'b':4},{'a':5,'b':0}]
>>> list(map(lambda y:y['a']/y['b'] if (y.get("b") != 0) else None, x))
[2.0, 1.5, None]

I am not sure this would be an ideal solution as extra coding would be required to handle None values. Please suggest most appropriate solutions that don't have else condition in lambda expression.


  1. There could be a possibilities a can be missing from input. It throws KeyError-
>>> x = [{'a':10,'b':5},{'a':6,'b':4},{'b':1}]
>>> list(map(lambda y: y['a']/y['b'], x))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 1, in <lambda>
KeyError: 'a'

Please suggest to handle both scenario as well. Other alternative methods are available to handle easily this scenario but I want to stick with lambda expression if it can be possible. Thanks in advance for help.

CodePudding user response:

You can use complex expressions in an a if b else c construct:

result = list(map(lambda y: y['a']/y['b'] if (y.get("b") != 0) and 'a' in y else None, x))

Your best bet is to create an auxiliary function to be passed into map, rather than trying to force a lambda to do what you want.

def mapping_function(d):
   if d.get('b', 0) == 0 or 'a' not in d:
       return None
   else:
       return d['a']/d['b']

result = list(map(mapping_function, x))

However, you cannot avoid having None appear in your list if you insist on using map. If instead, you use a list comprehension, you can omit invalid dictionaries:

result = [d['a']/d['b'] for d in x if d.get('b', 0) == 0 or 'a' not in d]

Of course, you can also use filter to remove them:

result = list(filter(lambda v: v is not None, map(lambda y: y['a']/y['b'] if (y.get("b") != 0) and 'a' in y else None, x)))
  • Related