Python:将None转换为空字符串的最惯用方式?


156

做以下事情的最惯用的方法是什么?

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)

7
我喜欢您的原始语法。我认为它已经很清楚并且易于阅读。
GuiSim

1
@GuiSim:我可能有偏见,但我的回答几乎像是一个普通的英语句子……
SilentGhost 2009年

1
“如果s为None,则返回一个空字符串;否则,返回s [string of]。” 问题中的代码阅读起来也像普通的英语句子。

a)如果字符串s来自未找到键的字典查找,则使用dict.get(key, '')
smci

b)如果只希望此字符串转换用于输出格式设置(例如,用于打印),则可以直接执行'... {}'。format(dict.get(1))`
smci

Answers:


94

如果您实际上希望函数的行为类似于str()内置函数,但是当参数为None时返回空字符串,请执行以下操作:

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

我保留了else,但是感谢str(s)技巧,因此可以处理多种类型。真好!
Mark Harrison

11
或者干脆xstr = lambda s: '' if s is None else str(s)
迈克尔Mior

2
我喜欢打字,if not s:而不是if s is None
guneysus 2015年

6
@guneysus不同:not False == True但是False is None == False
林恩

谢谢@Lynn,你是对的。我意识到我的错。但我知道(或假设)s始终是str / unicode类型或None。是的,这False是一个值,但是我更喜欢这种方式来节省我的键盘和眼睛;)
guneysus 2016年

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

3
该语法在2.5中引入;对于早期版本的Python,可以使用return s is not None and s or ''
本·布兰克

8
我会转过头来强调一个比较普通的情况:如果s不是其他““,则返回s
Ber

5
@Ber:我会保持原样,以避免出现双重负面影响。
Nikhil Chelliah 2009年

8
这是一个很好的例子,说明了如何.. and .. or ..失败以及为什么首选if-else。中有两个细微的错误s is not None and s or ''

1
return '' if not s else str(s)
Iqbal

107

可能最短的是 str(s or '')

因为None为False,如果x为false,则“ x或y”返回y。有关详细说明,请参见布尔运算符。它很短,但不是很明确。


1
太好了,谢谢!从来没有想过使用or这种方式
user25064

15
如果s为0,False或任何虚假值,则此方法不起作用
wisbucky

4
好吧,这在操作要求中没有提到,所以我在这里看不到你的意思。
dorvak

2
@dorvak OP对输出应该为''iff 的要求非常明确s is None。所有其他输入都应返回s(或str(s)在修订的请求中)。
StvnW

2
@fortea:那行不通。如果sNone,结果xstr()应该是一个空字符串,但str(None)给人的字符串"None",这是返回什么(因为字符串"None"不是falsy值。
dreamlax

97

如果您知道该值将始终是字符串或无:

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
迄今为止最pythonic的。使用python将None,空列表,空字符串,0等视为false的事实。还使用以下事实:or语句返回为true的第一个元素,或返回给or(或ors组)的最后一个元素。这也使用lambda函数。我会给你+10,但显然不会让我。
马特

11
这将转换0和False(以及传递给bool()时评估为False的其他任何值)
Arkady

9
我不认为这是“迄今为止最pythonic的”。在其他语言中,这是一个常见的习惯用法,我认为在Python中使用它不是错误的,但是条件表达式的引入正是为了避免此类技巧。
罗伯托·邦瓦莱特

2
这使得[]{}等具有与相同的结果None,这是不希望的。 xstr(False),尤其应"False"改为""。滥用lambdas就是一个糟糕的例子,请使用def xstr(s): return s or ""ir来将它们全部放在一行上。

5
请注意,我在一开始就用“如果您知道该值将始终为字符串或无”来限定答案。
Vinay Sajip,2010年

59

return s or '' 可以很好地解决您所说的问题!


4
值得注意的是,这将给予s为假或0不同的结果(这是不是原始字符串的问题,而是一个更新)
Oddthinking

@Oddthinking s = Falses = 0最有可能是边缘的情况下它的使用,可以通过写它能够很容易地缓解return str(s or '')
威廉·Ketwich

@WillemvanKetwich:这有完全相同的问题:s(False)应该返回'False',而不是'。s(0)应该返回“ 0”,而不是“”。同样,对于定义__bool__或__nonzero__的对象。
奇怪的想'17

@奇怪的我明白你的意思了。无论如何,如果它专用于字符串对象(例如在OP的问题中),则不成问题。
Willem van Ketwich '17

@WillemvanKetwich:看看我的评论中更新的问题和警告-已经涵盖了,
Oddthinking '17


8

功能方式(单线)

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

1
“ def xstr(s):如果s为None,则返回” s”也是在线的,毕竟python对空格的要求并不严格
SilentGhost 2009年

2
这不是真正的一线纸,只写在一行g
Dario

1
从什么意义上说它不是真正的在线用户?检查您的解释器-这不是语法错误。出于所有目的和目的,它比lambda ^ _ ^更为真实
SilentGhost

2
应该使用def而不是将lambda分配给变量的PEP 8种。lambda的唯一真正优势是您可以将其作为表达式的一部分进行编写(例如传递给另一个函数),而这种优势在这种代码中就消失了。我也曾经这样做,直到我发现def可以写成一行,然后PEP 8向我展示了前进的道路。始终遵循python诸神。
Guy


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

我认为,这是相当蟒蛇的-这个怎么样:“ xstr = lambda s:{None:”}。get(s,s)“ –将整个事情简化为单一形式。
根,

14
不必要的慢(额外的字典构造和查找),并且更难阅读。相当不可思议。
三联画

你是对的。它相当完善,但是避免了python字节码中的条件跳转。
tobidope

4
get()函数调用隐含至少一个附加的条件跳转。
三联画

1
在不知道问题或抬头的情况下,我无法说出应该做些什么get
Dario

5

我使用max函数:

max(None, '')  #Returns blank
max("Hello",'') #Returns Hello

就像一个吊饰;)只需将字符串放在函数的第一个参数中即可。


5
之所以有效,是因为'str'>'NoneType',并且是CPython特定的。在手册中:“除数字外,其他类型的对象均按其类型名称排序”。另外,由于不再允许进行类型间比较(TypeError:不可排序的类型:str()> NoneType()),因此这在Python 3000中不起作用。请参阅Python如何比较string和int?
plok

知道了,谢谢。因此,推进python 3.x兼容代码不是一个好主意。
radtek 2014年

4

如果您需要与Python 2.4兼容,请在上面进行修改

xstr = lambda s: s is not None and s or ''

2

如果要格式化字符串,则可以执行以下操作:

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)

1
def xstr(s):
    return s if s else ''

s = "%s%s" % (xstr(a), xstr(b))

5
这将为所有类似错误的值返回一个空字符串,这不是发布者所要求的。
三联画

1

在下面说明的场景中,我们总是可以避免类型转换。

customer = "John"
name = str(customer)
if name is None
   print "Name is blank"
else: 
   print "Customer name : " + name

在上面的示例中,如果变量customer的值为None,则在分配给'name'的同时进一步进行强制转换。“ if”子句中的比较将始终失败。

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)

上面的示例将正常工作。当从URL,JSON或XML中获取值,甚至值需要进一步的类型转换以进行任何操作时,这种情况非常普遍。


0

使用短路评估:

s = a or '' + b or ''

由于+对字符串不是很好的操作,因此最好使用格式字符串:

s = "%s%s" % (a or '', b or '')

2
对于所有类似false的值,这也将把'a'转换为空字符串,而不仅仅是None。例如,空元组,列表和字典将转换为空字符串,这不是OP指定的。
三联画

+是两个字符串的完美运算符。当您尝试使用它来加入数十个遇到麻烦的地方时。对于两个,它可能会比其他选项更快。无论哪种方式,都是在噪音中。
kquinn

对我来说+1,因为这正是我的需要:对于我来说,lambda或替换单个运算符(or)的函数似乎有点过大……我没有其他虚假值的情况-str或None。除了对+运营商的评论(这可能取决于特定的情况并且可能需要基准测试)之外,此答案确实并不值得-1
城市

-3

如果使用的是python v3.7,请使用F字符串

xstr = F"{s}"

1
这是错误的,'None'如果s是则返回字符串None
劳伦斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.