如何检查字符串是不是为空?
Posted
技术标签:
【中文标题】如何检查字符串是不是为空?【英文标题】:How to check if the string is empty?如何检查字符串是否为空? 【发布时间】:2012-03-23 07:32:32 【问题描述】:Python 是否有类似空字符串变量的功能:
if myString == string.empty:
无论如何,检查空字符串值的最优雅的方法是什么?我发现硬编码""
每次检查空字符串都不太好。
【问题讨论】:
""
怎么不好吗?
【参考方案1】:
空字符串是“假的”(python 2 或 python 3 参考),这意味着它们在布尔上下文中被认为是假的,因此您可以这样做:
if not myString:
如果您知道您的变量是一个字符串,这是首选方式。如果您的变量也可以是其他类型,那么您应该使用myString == ""
。请参阅Truth Value Testing 上的文档以了解在布尔上下文中为 false 的其他值。
【讨论】:
小心,因为很多其他的东西也是假的。 我以前从未听说过 falsy 这个词。这是否意味着它返回false? @Joan:它在布尔上下文中评估为假。 OP 想知道变量是否为空字符串,但如果myString
是None
、0
、False
等,您也将输入if not myString:
块。所以如果你不确定myString
是什么类型,你应该使用if myString == "":
来确定它是否是一个空字符串而不是其他一些假值。
@AndrewClark,对于这种情况,我们可以使用if myString in (None, '')
或@Bartek,if myString in (None, '') or not myString.strip()
,而不是if myString == ...
表达式链【参考方案2】:
来自PEP 8,在“Programming Recommendations” section:
对于序列(字符串、列表、元组),使用空序列为假这一事实。
所以你应该使用:
if not some_string:
或:
if some_string:
澄清一下,如果序列为空或不为空,则在布尔上下文中评估为False
或True
。它们不等于False
或True
。
【讨论】:
PS:在 PEP 的辩护中,有人可能会争辩说“x is false”(小写 false)已经意味着,而不是意味着x == False
。但恕我直言,鉴于目标受众,仍然欢迎澄清。【参考方案3】:
最优雅的方法可能是简单地检查它的真假,例如:
if not my_string:
但是,您可能希望去除空白,因为:
>>> bool("")
False
>>> bool(" ")
True
>>> bool(" ".strip())
False
但是,您可能应该更明确一点,除非您确定该字符串已通过某种验证并且是可以通过这种方式测试的字符串。
【讨论】:
【参考方案4】:我会在剥离之前测试虚无。此外,我会使用空字符串为 False(或 Falsy)这一事实。这种方式类似于Apache's StringUtils.isBlank或Guava's Strings.isNullOrEmpty
这是我用来测试字符串是否为 None 或 Empty 或 Blank 的:
def isBlank (myString):
if myString and myString.strip():
#myString is not None AND myString is not empty or blank
return False
#myString is None OR myString is empty or blank
return True
并且,与测试字符串是否为 None NOR Empty NOR Blank 完全相反:
def isNotBlank (myString):
if myString and myString.strip():
#myString is not None AND myString is not empty or blank
return True
#myString is None OR myString is empty or blank
return False
以上代码的更简洁形式:
def isBlank (myString):
return not (myString and myString.strip())
def isNotBlank (myString):
return bool(myString and myString.strip())
【讨论】:
为什么不if mystring and not mystring.strip()
?
和string and not string.isspace()
有什么区别?
对于那些关心这些事情的人来说更简洁:def isBlank(s): return not (s and s.strip())
和 def isNotBlank(s): return s and s.strip()
。
s.strip()
分配一个新字符串,纯属浪费。使用string.isspace()
这个答案不是很pythonic【参考方案5】:
我曾经写过类似 Bartek 的回答和 javascript 启发的东西:
def is_not_blank(s):
return bool(s and not s.isspace())
测试:
print is_not_blank("") # False
print is_not_blank(" ") # False
print is_not_blank("ok") # True
print is_not_blank(None) # False
【讨论】:
为什么不只是return bool(s.strip())
AttributeError: 'NoneType' object has no attribute 'strip'
s.strip()
分配一个新字符串,纯属浪费。使用string.isspace()
"".isspace()
是False
@Danon 不会通过第一次测试s and
并且会短路。【参考方案6】:
唯一真正可靠的方法是:
if "".__eq__(myString):
所有其他解决方案都可能存在检查失败的问题和极端情况。
如果myString
是继承自str
并覆盖__len__()
方法的类的对象,len(myString)==0
可能会失败。
如果myString
覆盖__eq__()
和__ne__()
,同样myString == ""
和myString.__eq__("")
可能会失败。
由于某种原因,如果 myString
覆盖 __eq__()
,"" == myString
也会被愚弄。
myString is ""
和 "" is myString
是等价的。如果myString
实际上不是字符串而是字符串的子类,它们都会失败(两者都将返回False
)。此外,由于它们是身份检查,它们工作的唯一原因是因为 Python 使用字符串池(也称为字符串实习),如果它被实习,它使用相同的字符串实例(见这里:Why does comparing strings using either '==' or 'is' sometimes produce a different result?)。而""
从一开始就在 CPython 中实习
身份检查的最大问题是 String Internment (据我所知)没有标准化哪些字符串被实习。这意味着,理论上 ""
不需要实习,这取决于实现。
真正不能被愚弄的唯一方法是开头提到的方法:"".__eq__(myString)
。由于这显式调用了空字符串的 __eq__()
方法,因此无法通过覆盖 myString 中的任何方法来欺骗它,并且可以可靠地与 str
的子类一起使用。
如果对象覆盖了它的 __bool__()
方法,那么依赖字符串的虚假性也可能不起作用。
这不仅是理论上的工作,而且实际上可能与实际使用相关,因为我之前已经看到框架和库子类化 str
并且使用 myString is ""
可能会在那里返回错误的输出。
此外,使用is
比较字符串通常是一个非常邪恶的陷阱,因为它有时会正常工作,但在其他时候却不行,因为字符串池遵循非常奇怪的规则。
也就是说,在大多数情况下,上述所有解决方案都可以正常工作。这个帖子主要是学术工作。
【讨论】:
@simpleuser 你当然是对的。在现实世界中,使用字符串的虚假性或将其与空字符串进行比较是完全可以的。这个这里的答案是故意的。【参考方案7】:测试空字符串或空字符串(更短的方法):
if myString.strip():
print("it's not an empty or blank string")
else:
print("it's an empty or blank string")
【讨论】:
如果myString = None
,会引发异常。最好使用@vault 的answer
@Dominik if myString isinstance(myString, int)
也会引发异常。你想说啥? OP 询问测试空字符串的方法,他的问题不包括类型检查。【参考方案8】:
如果你想区分空字符串和空字符串,我建议使用if len(string)
,否则,我建议像其他人所说的那样简单地使用if string
。不过,关于充满空格的字符串的警告仍然适用,所以不要忘记strip
。
【讨论】:
我不知道你为什么要避免使用“”,除非它以某种方式影响性能,但我更喜欢你的答案,而不是有无数赞成票的答案,因为它不那么令人困惑。但是,我想指出,一个空列表显然也是 False。【参考方案9】:if stringname:
在字符串为空时给出false
。我想它不能比这更简单。
【讨论】:
【参考方案10】:我发现硬编码(原文如此)“”每次检查空字符串都不太好。
清洁代码方法
这样做:foo == ""
是非常糟糕的做法。 ""
是一个神奇的值。你永远不应该检查魔法值(通常称为magical numbers)
您应该做的是与描述性变量名称进行比较。
描述性变量名称
有人可能认为“empty_string”是一个描述性变量名。 不是。
在你去empty_string = ""
之前,认为你有一个很棒的变量名可以比较。这不是“描述性变量名”的意思。
一个好的描述性变量名称基于其上下文。 您必须考虑空字符串 是什么。
它来自哪里。 为什么会出现。 为什么需要检查。简单的表单域示例
您正在构建一个用户可以输入值的表单。您想检查用户是否写了一些东西。
一个好的变量名可能是not_filled_in
这使得代码非常可读
if formfields.name == not_filled_in:
raise ValueError("We need your name")
完整的 CSV 解析示例
您正在解析 CSV 文件并希望将空字符串解析为 None
(由于 CSV 完全基于文本,因此如果不使用预定义的关键字,它无法表示 None
)
一个好的变量名可能是CSV_NONE
如果您有一个新的 CSV 文件来表示 None
的另一个字符串不是 ""
,这将使代码易于更改和调整
if csvfield == CSV_NONE:
csvfield = None
没有关于这段代码是否正确的问题。很明显,它做了它应该做的。
比较一下
if csvfield == EMPTY_STRING:
csvfield = None
这里的第一个问题是,为什么空字符串需要特殊处理?
这将告诉未来的编码人员空字符串应始终被视为None
。
这是因为它混合了业务逻辑(CSV 值应该是None
)和代码实现(我们实际比较的是什么)
两者之间需要有一个separation of concern。
【讨论】:
真的需要那么麻烦才能避免出现“”吗?在比较的上下文中,空白字符串还有什么含义? 正如我在回答中所写,CSV 不能在不使用字符串的情况下表示 null。如果您没有上下文,那么恭喜!大多数代码不是。 你说“not_filled_in”比“empty_string”更具描述性?我说你很高。 @TuncayGöncüoğlu “空字符串”没有描述 if 语句测试的内容。 我不同意这个答案。幻数不好,这是有道理的。魔法值一般也是如此。但""
不是魔法值,同样True
、False
或None
也不是魔法值。【参考方案11】:
a = ''
b = ' '
a.isspace() -> False
b.isspace() -> True
【讨论】:
真的不明白这个解决方案有什么好处。问题是关于测试字符串是否为空。如果您设置a='a'
,您将得到a.isspace() -> False
,但a
在该帐户上不会是空字符串。【参考方案12】:
这个怎么样?也许它不是“最优雅的”,但它看起来相当完整和清晰:
if (s is None) or (str(s).strip()==""): // STRING s IS "EMPTY"...
【讨论】:
在大多数情况下,包含空格的字符串不是“空的”。 我假设你的意思只是空白?你指的是我对 strip() 的使用?对于大多数用途来说,它是空的!复合类似 s.trim().isEmpty() 之类的东西很可笑 嘿@Chris Johnson,您是否看到这里的大多数答案也使用 strip() ?你投了我们所有人的票,还是只投了我一票?【参考方案13】:回复@1290。抱歉,无法在 cmets 中格式化块。 None
值在 Python 中不是空字符串,(空格)也不是。 Andrew Clark 的答案是正确的:if not myString
。 @rouble 的答案是特定于应用程序的,不回答 OP 的问题。如果你对什么是“空白”字符串采用特殊的定义,你会遇到麻烦。特别是,标准行为是str(None)
产生'None'
,一个非空字符串。
但是,如果您必须将 None
和(空格)视为“空白”字符串,这里有一个更好的方法:
class weirdstr(str):
def __new__(cls, content):
return str.__new__(cls, content if content is not None else '')
def __nonzero__(self):
return bool(self.strip())
例子:
>>> normal = weirdstr('word')
>>> print normal, bool(normal)
word True
>>> spaces = weirdstr(' ')
>>> print spaces, bool(spaces)
False
>>> blank = weirdstr('')
>>> print blank, bool(blank)
False
>>> none = weirdstr(None)
>>> print none, bool(none)
False
>>> if not spaces:
... print 'This is a so-called blank string'
...
This is a so-called blank string
满足@rouble 要求,同时不破坏字符串的预期bool
行为。
【讨论】:
python -c "if (str(None) == 'None'): print ('OMG, WHY ??')"
【参考方案14】:
我对 ''、' '、'\n' 等字符串进行了一些实验。当且仅当变量 foo 是具有至少一个非空白字符的字符串时,我希望 isNotWhitespace 为 True。我正在使用 Python 3.6。这是我最终得到的结果:
isWhitespace = str is type(foo) and not foo.strip()
isNotWhitespace = str is type(foo) and not not foo.strip()
如果需要,将其包装在方法定义中。
【讨论】:
【参考方案15】:not str(myString)
对于空字符串,此表达式为 True。非空字符串、None 和非字符串对象都会产生 False,但需要注意的是对象可能会覆盖 __str__ 以通过返回虚假值来阻止此逻辑。
【讨论】:
【参考方案16】:当您逐行读取文件并想确定哪一行为空时,请确保您将使用.strip()
,因为“空”行中有换行符:
lines = open("my_file.log", "r").readlines()
for line in lines:
if not line.strip():
continue
# your code for non-empty lines
【讨论】:
【参考方案17】:你可以看看这个Assigning empty value or string in Python
这是关于比较空字符串。因此,您可以使用""
测试空字符串,而不是使用not
测试空字符串...
【讨论】:
【参考方案18】:对于那些期望像 apache StringUtils.isBlank 或 Guava Strings.isNullOrEmpty 这样的行为的人:
if mystring and mystring.strip():
print "not blank string"
else:
print "blank string"
【讨论】:
【参考方案19】:如果你只是使用
not var1
无法区分布尔变量False
和空字符串''
:
var1 = ''
not var1
> True
var1 = False
not var1
> True
但是,如果您在脚本中添加一个简单的条件,就会有所不同:
var1 = False
not var1 and var1 != ''
> True
var1 = ''
not var1 and var1 != ''
> False
【讨论】:
【参考方案20】:如果这对某人有用,这是我构建的一个快速函数,用于在列表列表中用 N/A 替换空白字符串(python 2)。
y = [["1","2",""],["1","4",""]]
def replace_blank_strings_in_lists_of_lists(list_of_lists):
new_list = []
for one_list in list_of_lists:
new_one_list = []
for element in one_list:
if element:
new_one_list.append(element)
else:
new_one_list.append("N/A")
new_list.append(new_one_list)
return new_list
x= replace_blank_strings_in_lists_of_lists(y)
print x
这对于将列表列表发布到不接受某些字段(架构中标记为 NN 的字段。在我的情况下,这是由于复合主键造成的)的 mysql 数据库中的数据库非常有用。
【讨论】:
【参考方案21】:如果您不能完全确定您的输入是否真的是一个字符串,我建议您另外使用isinstance(object, classinfo)
link,如示例所示。
如果不是,列表或True
bool 值也可以评估为True
。
<script type="text/javascript" src="//cdn.datacamp.com/dcl-react.js.gz"></script>
<div data-datacamp-exercise data-lang="python">
<code data-type="sample-code">
def test_string(my_string):
if isinstance(my_string, str) and my_string:
print("It's a me, String! -> " + my_string)
else:
print("Nope. No, String")
def not_fully_test_string(my_string):
if my_string:
print("It's a me, String??? -> " + str(my_string))
else:
print("Nope. No, String")
print("Testing String:")
test_string("")
test_string(True)
test_string(["string1", "string2"])
test_string("My String")
test_string(" ")
print("\nTesting String or not?")
not_fully_test_string("")
not_fully_test_string(True)
not_fully_test_string(["string1", "string2"])
not_fully_test_string("My String")
not_fully_test_string(" ")
</code>
</div>
【讨论】:
【参考方案22】:正如prmatta在上面发布的,但有错误。
def isNoneOrEmptyOrBlankString (myString):
if myString:
if not myString.strip():
return True
else:
return False
return False
【讨论】:
刚刚测试过:他的代码为""
和 " "
返回 True,为 "a"
返回 False(正如预期的那样)。您的代码返回相同,除了它返回 True 的空字符串,它不应该返回。
sry 太累了:您的代码为空字符串返回 False。
此代码错误。如果字符串为空或无,则返回 False。以上是关于如何检查字符串是不是为空?的主要内容,如果未能解决你的问题,请参考以下文章