13

I have the following lambda function:

f = lambda x: x == None and '' or x

It should return an empty string if it receives None as the argument, or the argument if it's not None.

For example:

>>> f(4)
4
>>> f(None)
>>>

If I call f(None) instead of getting an empty string I get None. I printed the type of what the function returned and I got NoneType. I was expecting string.

type('') returns string, so I'd like to know why the lambda doesn't return an empty string when I pass None as an argument.

I'm fairly new to lambdas so I might have misunderstood some things about how they work.

1
  • 2
    You've committed one of the Classic Blunders... Commented Apr 3, 2010 at 20:43

6 Answers 6

28

use the if else construct

f = lambda x:'' if x is None else x
Sign up to request clarification or add additional context in comments.

Comments

9

The problem in your case that '' is considered as boolean False. bool('') == False. You can use

f =lambda x:x if x is not None else ''

Comments

4

The problem is that Python treats the empty string as False. When you pass None to your function, it evaluates to:

None == None and '' or None

which (effectively) becomes:

True and False or None

then:

False or None

and finally:

None

One solution would be:

lambda x: x if x is not None else ''

If you know x will be either a string or None, then you can leverage the fact that None is also a False value in Python:

lambda x: x or ''

Comments

3

Python gives and a higher precedence than or, so the parentheses fall here:

lambda x: (x == None and '') or x

When passed None, this becomes (True and '') or None. Python’s boolean operators work by returning one argument or another (whence this little trick), so this reduces to '' or None, and finally None.

This little trick stems from back before Python 2.5, which didn't have the conditional operator. The caveat, which you just ran into, is that it doesn’t behave as expected when True branch has a False value. Unless you’re concerned with Python ≤ 2.4, just use the conditional operator.

Comments

2

It's not lambdas that are the problem here. It's the pythonic if/else expressiong you are using there.

(condition) and (expression1) or (expression2) most of the times means the (condition) ? (expression1) : (expression2) you'd expect, except when expression1 evaluates to False.

This is because the whole thing is evaluated in order. If condition fails, expression1 is evaluated. If it is True, it is returned, due to short circuit evaluation, hence the expected behaviour. If not, expression2 is returned. '' evaluates to False.

1 Comment

Yeah the and/or pattern is not very Pythonic.. don't use it! Keep It Simple, Stupid!
2

Try short-circuit evaluation:

 >>> g = lambda x: x or ''
 >>> g(3)
 3
 >>> g(None)
 ''
 >>> # beware that ...
 >>> g(0)
 ''

1 Comment

I don't think g(0) returns what OP wants.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.