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 -
0
can be come at place ofb
which throwZeroDivisionError
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.
- There could be a possibilities
a
can be missing from input. It throwsKeyError
-
>>> 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)))