I have dict comprehension with lambda function and scalar:
d = {k: lambda x : x.sum() if 'a' in k else 'yes' for k in ['bac','sss','asa']}
print (d)
{'bac': <function <dictcomp>.<lambda> at 0x00000000031891E0>,
'sss': <function <dictcomp>.<lambda> at 0x000000000D887EA0>,
'asa': <function <dictcomp>.<lambda> at 0x000000000D887B70>}
If want both scalars it working nice:
d = {k: 'no' if 'a' in k else 'yes' for k in ['bac','sss','asa']}
print (d)
{'bac': 'no', 'sss': 'yes', 'asa': 'no'}
Expected output - combination of scalars and lambda function:
print (d)
{'bac': <function <dictcomp>.<lambda> at 0x00000000031891E0>,
'sss': 'yes',
'asa': <function <dictcomp>.<lambda> at 0x000000000D887B70>}
What is happening? Why it is not working? What is the correct approach?
Your syntax is parsed as follows (note the location of the parentheses):
{k: lambda x : (x.sum() if 'a' in k else 'yes') for k in ['bac','sss','asa']}
# ^ ^
You want:
{k: (lambda x : x.sum()) if 'a' in k else 'yes' for k in ['bac','sss','asa']}
# ^ ^
This is because lambda
has lower precedence than if
-else
.
A simpler example also illustrates this:
>>> lambda x: 0 if False else True
<function <lambda> at 0x7efdbe55abf8>
>>> lambda x: (0 if False else True)
<function <lambda> at 0x7efdbe55ac80>
>>> (lambda x: 0) if False else True
True
d = {k: (lambda x : x.sum()) if 'a' in k else 'yes' for k in ['bac','sss','asa']}
should work. The reason (as far as I understand) is that boundaries for parsing lambda is overlapping with your comprehension — basically, python parsing your lambda as x.sum() if 'a' in k else 'yes'
— with reference to locals
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With