What is the most idiomatic way to do the following?
def xstr(s):
if s is None:
return ''
else:
return s
s = xstr(a) + xstr(b)
update: I'm incorporating Tryptich's suggestion to use str(s), which makes this routine work for other types besides strings. I'm awfully impressed by Vinay Sajip's lambda suggestion, but I want to keep my code relatively simple.
def xstr(s):
if s is None:
return ''
else:
return str(s)
s
came from a dict lookup where the key was not found, then use dict.get(key, '')
Probably the shortest would be str(s or '')
Because None is False, and "x or y" returns y if x is false. See Boolean Operators for a detailed explanation. It's short, but not very explicit.
def xstr(s):
return '' if s is None else str(s)
return s is not None and s or ''
.
.. and .. or ..
fails and why if-else is preferred. There're two subtle bugs in s is not None and s or ''
.
return '' if not s else str(s)
If you actually want your function to behave like the str()
built-in, but return an empty string when the argument is None, do this:
def xstr(s):
if s is None:
return ''
return str(s)
xstr = lambda s: '' if s is None else str(s)
if not s:
instead of if s is None
not False == True
but False is None == False
.
s
always a in str/unicode type or None
. Yes, False
is a value but I prefer this way that saves my keyboard and eyes ;)
If you know that the value will always either be a string or None:
xstr = lambda s: s or ""
print xstr("a") + xstr("b") # -> 'ab'
print xstr("a") + xstr(None) # -> 'a'
print xstr(None) + xstr("b") # -> 'b'
print xstr(None) + xstr(None) # -> ''
[]
, {}
, etc. give the same result as None
, which isn't desired. xstr(False)
, in particular, should be "False"
instead of ""
. Abusing lambdas makes for a poor example, use def xstr(s): return s or ""
ir you want to keep it all on one line.
return s or ''
will work just fine for your stated problem!
s = False
or s = 0
would most likely be an edge case in it's use and could be easily mitigated by writing it as return str(s or '')
def xstr(s):
return s or ""
''
for 0
, []
, {}
, False
and false-like values, which is not what the poster asked for.
def xstr(s): return str(s) or ""
Functional way (one-liner)
xstr = lambda s: '' if s is None else s
A neat one-liner to do this building on some of the other answers:
s = (lambda v: v or '')(a) + (lambda v: v or '')(b)
or even just:
s = (a or '') + (b or '')
(lambda v: v or '')
?
False
and empty list will also be turned to ''.
0
, etc.
UPDATE:
I mainly use this method now:
some_string = None
some_string or ''
If some_string was not NoneType
, the or
would short circuit there and return it, otherwise it returns the empty string.
OLD:
Max function worked in python 2.x but not in 3.x:
max(None, '') # Returns blank
max("Hello", '') # Returns Hello
def xstr(s):
return {None:''}.get(s, s)
get
.
Variation on the above if you need to be compatible with Python 2.4
xstr = lambda s: s is not None and s or ''
If it is about formatting strings, you can do the following:
from string import Formatter
class NoneAsEmptyFormatter(Formatter):
def get_value(self, key, args, kwargs):
v = super().get_value(key, args, kwargs)
return '' if v is None else v
fmt = NoneAsEmptyFormatter()
s = fmt.format('{}{}', a, b)
def xstr(s):
return s if s else ''
s = "%s%s" % (xstr(a), xstr(b))
We can always avoid type casting in scenarios explained below.
customer = "John"
name = str(customer)
if name is None
print "Name is blank"
else:
print "Customer name : " + name
In the example above in case variable customer's value is None the it further gets casting while getting assigned to 'name'. The comparison in 'if' clause will always fail.
customer = "John" # even though its None still it will work properly.
name = customer
if name is None
print "Name is blank"
else:
print "Customer name : " + str(name)
Above example will work properly. Such scenarios are very common when values are being fetched from URL, JSON or XML or even values need further type casting for any manipulation.
Use short circuit evaluation:
s = a or '' + b or ''
Since + is not a very good operation on strings, better use format strings:
s = "%s%s" % (a or '', b or '')
+
is a perfectly good operator for two strings. It's when you try to use it to join dozens that you have trouble. For two, it'll probably be faster than other options; either way, it's in the noise.
or
) seems a bit of an overkill for me... I dont have cases of other falsly values - either str or None. Other than the comment on the +
operator, which might depend on specific scenario and might need benchmarking, this answer does not deserve a -1
Use F string if you are using python v3.7
xstr = F"{s}"
'None'
if s
is None
.
Success story sharing
or
this ways
is 0, False, or any falsy value''
iffs is None
. All other input should returns
(orstr(s)
in the revised request).s
isNone
, the result ofxstr()
should be an empty string, butstr(None)
gives the string"None"
, which is what is returned (since the string"None"
is not a falsy value.