将None转换为空字符串的最常用方法是什么?

214
什么是最地道的方法来完成以下任务?
def xstr(s):
    if s is None:
        return ''
    else:
        return s

s = xstr(a) + xstr(b)

更新:我正在采用Tryptich的建议使用str(s),这使得这个例程适用于除了字符串之外的其他类型。我对Vinay Sajip的lambda建议印象深刻,但我希望保持我的代码相对简单。
def xstr(s):
    if s is None:
        return ''
    else:
        return str(s)

9
我喜欢你的原始语法。我认为它已经相当清晰易读了。 - GuiSim
1
@GuiSim:我可能有偏见,但我的答案读起来几乎像一个普通的英语句子... - SilentGhost
1
如果s为None,则返回一个空字符串;否则,返回s的字符串。问题中的代码读起来就像是一个普通的英语句子。 - Roger Pate
3
如果字符串s来自于字典查找,但是没有找到对应的键值,则使用dict.get(key, '') - smci
如果你只想要这个字符串转换用于输出格式化(例如用于打印),那么你可以直接使用 '... {}'.format(dict.get(1))`. - smci
17个回答

233

可能最简短的方式就是str(s or '')

因为None为False,而 "x or y" 在x为假时返回y。详见布尔运算符的详细解释。这个方法很短,但不是很清晰易懂。


2
太棒了,谢谢!从来没有想过可以这样使用 or - user25064
24
如果s的值为0、False或任何“假值”,则此方法无效。 - wisbucky
8
嗯,这并没有在原帖的要求中提到,所以我不明白你的意思。 - dorvak
4
@dorvak的要求非常明确,要求输出结果当且仅当s为None时为''。所有其他输入都应返回s(或在修改后的请求中返回str(s))。 - StvnW
3
@fortea:那不行。如果sNone,则xstr()的结果应该是一个空字符串,但str(None)会返回字符串“None”,这就是实际返回的结果(因为字符串“None”不是假值)。 - dreamlax
显示剩余2条评论

173
def xstr(s):
    return '' if s is None else str(s)

4
这种语法是在2.5版本中引入的;对于早期版本的Python,您可以使用return s is not None and s or '' - Ben Blank
8
如果需要强调更普遍的情况,我会将其改写为:如果s不是None,则返回s,否则返回""。 - Ber
5
@Ber:我会保持原样,以避免双重否定。 - Nikhil
8
这是一个很好的例子,说明了 .. and .. or .. 失败的原因,以及为什么 if-else 更可取。在s is not None and s or ''中存在两个微妙的 bug。 - Roger Pate
1
return '' if not s else str(s) - Iqbal
显示剩余3条评论

117

如果你想让你的函数像内置函数str()一样运作,但当参数为None时返回空字符串,请使用以下代码:

def xstr(s):
    if s is None:
        return ''
    return str(s)

1
我会保留else,但感谢你的str(s)提示,这样就可以处理多种类型了。太好了! - Mark Harrison
20
这段代码的意思是:定义一个名为xstr的函数,它接受一个参数s,如果s为空,则返回空字符串,否则返回s的字符串形式。 - Michael Mior
3
我喜欢打 if not s: 而不是 if s is None - guneysus
9
它们并不相同:not False == True 但是 False is None == False - Lynn
谢谢@Lynn,你是对的。我意识到了我的错误。但我知道(或者假设)s总是一个str/unicode类型或者None。是的,False是一个值,但我更喜欢这种方式,因为它可以节省我的键盘和眼睛 ;) - guneysus
@guneysus 仍然。如果你想将 False 转换为字符串,可以使用 str(False),但是 xtr(False) 将返回 ''。取决于你想要的行为,而不是你喜欢还是不喜欢输入 not s - user4396006

107

如果你知道这个值只会是字符串或者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) # -> ''

1
到目前为止最符合Python风格的。利用了Python将None、空列表、空字符串、0等视为假的特性。还利用了or语句返回第一个为真的元素或最后一个给定的元素(或者是or组)。此外,这也使用了lambda函数。我想给你+10分,但显然它不会让我这么做。 - Matt
12
这将转换0和False(以及任何其他传递给bool()时求值为False的内容) - Arkady
9
我不认为这是“迄今为止最符合Python风格的”。虽然在其他语言中,这是一种常见的习惯用法,但我认为在Python中使用它并不是错误的,只是条件表达式被引入的目的恰恰是为了避免像这样的技巧。 - Roberto Bonvallet
2
这会使[]{}等产生与None相同的结果,这是不希望的。特别是,xstr(False)应该是"False"而不是""。滥用lambda表达式会导致一个糟糕的例子,如果你想将其全部放在一行上,请使用def xstr(s): return s or "" - Roger Pate
5
请注意,我在一开始就用“如果您知道该值始终是字符串或None”限定了我的答案。 - Vinay Sajip
显示剩余2条评论

67

return s or '' 对于你所描述的问题完全可以胜任!


4
值得注意的是,当 s 为 False 或 0 时(这不是原始字符串问题,而是更新后的问题),会得到不同的结果。 - Oddthinking
2
@Oddthinking 如果s = False或者s = 0在使用中是一个边缘情况,那么通过编写return str(s or '')可以轻松地解决它。 - Willem van Ketwich
@WillemvanKetwich:这正是同样的问题:s(False)应该返回'False',而不是''。s(0)应该返回'0',而不是''。对于定义了__bool__或__nonzero__的对象也是如此。 - Oddthinking
@Oddthinking 我理解你的观点。无论如何,如果它仅用于字符串对象,例如在OP的问题中,这不应该是一个问题。 - Willem van Ketwich
@WillemvanKetwich:看一下更新后的问题和我评论中的注意事项——已经讨论过了。 - Oddthinking
像对@Krystian-Cybulski的答案进行评论一样: 只需在s周围放置str(...):def xstr(s): return str(s) or "" - fortea

15
def xstr(s):
   return s or ""

5
这将针对0、[]、{}、False以及类似false的值返回'',这不符合发帖者的要求。 - StvnW
1
将s用just put str([...])括起来: return str(s) or "" - fortea

12

更新:

我现在主要使用这种方法:

some_string = None
some_string or ''

如果some_string不是NoneType,则or会短路并返回它,否则返回空字符串。
OLD:
在Python 2.x中max函数有效,但在3.x中无效:
max(None, '')  # Returns blank
max("Hello", '') # Returns Hello

5
之所以有效,是因为'str'>'NoneType',而且这只适用于CPython。从手册可以看到:“除数字外的不同类型的对象按照它们的类型名排序”。此外,在Python 3000中将无法使用这种方法,因为禁止跨类型比较(TypeError: unorderable types: str() > NoneType())。请参见 How does Python compare string and int? - plok
好的,谢谢你告诉我。所以未来不建议使用 Python 3.x 兼容的代码。 - radtek

10

函数式方式(一行代码)

xstr = lambda s: '' if s is None else s

1
"def xstr(s): return '' if s is None else s " 是一种内联函数,Python 对于空格并不是那么严格的。" - SilentGhost
2
这不是真正的一行代码,只是写在一行里而已 g - Dario
1
它为什么不是真正的在线程序呢?在你的解释器中检查一下 - 它不是语法错误。从所有意义上讲,它比lambda更真实 ^_^ - SilentGhost
4
PEP 8指出,应该使用def而不是将lambda赋值给变量。 lambda的唯一真正优势是可以编写为表达式的一部分(例如传递给另一个函数),但在这种代码中,这种优势会失去。我以前也这样做,直到我注意到def可以写成一行,然后PEP 8向我展示了正确的方式。永远遵循Python之神的教诲。 - Guy

10
一个简洁的一行代码可以完成这个任务,基于其他答案的建议:
s = (lambda v: v or '')(a) + (lambda v: v or '')(b)

甚至只需:

s = (a or '') + (b or '')

为什么要提到 (lambda v: v or '') - Tvde1
为什么不呢?一份价格,两个技巧! - Willem van Ketwich
1
请注意,False 和空列表也会被转换为 '' - Nik O'Lai
same for 0, etc. - Walter Tross

6
def xstr(s):
    return {None:''}.get(s, s)

我认为这很符合Python的风格--这个怎么样:"xstr = lambda s : {None:''}.get(s,s)"--将整个东西简化成了一行代码。 - Juergen
16
不必要的缓慢(额外的字典构建和查找)使内容更难读。相当不符合Python的编写风格。 - Kenan Banks
你说得对。这种写法有点像 Perl,但它避免了在 Python 字节码中进行条件跳转。 - tobidope
4
get() 函数调用意味着至少有一个额外的条件跳转。 - Kenan Banks
1
如果不知道问题或查找get,我无法说出这个应该做什么。 - Dario
Dario:你能说出多少种编程语言的特性并解释它们的作用,而不需要提前了解或查阅资料呢? - Roger Pate

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接