如何检查字符串是否为空?

Python是否有类似于空字符串变量的东西,您可以在其中执行:

if myString == string.empty:

无论如何,检查空字符串值的最优雅的方法是什么?我发现每次检查空字符串的硬编码""都不太好。

2758364 次浏览

空字符串是“false sy”(python2python3引用),这意味着它们在布尔上下文中被认为是假的,所以你可以这样做:

if not myString:

如果您知道您的变量是字符串,这是首选方法。如果您的变量也可以是其他类型,那么您应该使用:

if myString == "":

有关布尔上下文中为false的其他值,请参阅真值检验上的留档。

最优雅的方法可能是简单地检查它是真还是假,例如:

if not my_string:

但是,您可能需要删除空白,因为:

 >>> bool("")False>>> bool("   ")True>>> bool("   ".strip())False

但是,您可能应该更明确一点,除非您确定此字符串已通过某种验证并且是可以通过这种方式测试的字符串。

PEP 8开始,在“编程建议”部分中:

对于序列(字符串、列表、元组),使用空序列为假的事实。

所以你应该使用:

if not some_string:

或:

if some_string:

澄清一下,如果序列是空的或不是空的,它们在布尔上下文中是评估FalseTrue。它们是不等于FalseTrue

当字符串为空时,if stringname:给出false。我想它不可能比这更简单了。

如果你想区分空字符串和空字符串,我建议使用if len(string),否则,我建议像其他人所说的那样简单地使用if string。关于充满空格的字符串的警告仍然适用,所以不要忘记strip

a = ''b = '   'a.isspace() -> Falseb.isspace() -> True

你可以看看这个在Python中分配空值或字符串

这是关于比较空字符串。因此,您可以测试您的字符串是否等于空字符串,而不是用not测试空字符串…

我会在剥离之前测试非性。此外,我会使用空字符串为False(或Falsy)的事实。这种方法类似于阿帕奇StringUtils.is空白番石榴的Strings.is空或空

这是我用来测试字符串是否为无或空或空白的:

def isBlank (myString):if myString and myString.strip():#myString is not None AND myString is not empty or blankreturn False#myString is None OR myString is empty or blankreturn True

并且,与测试字符串是否不是无NOR空NOR空白完全相反:

def isNotBlank (myString):if myString and myString.strip():#myString is not None AND myString is not empty or blankreturn True#myString is None OR myString is empty or blankreturn False

上面代码的更简洁形式:

def isBlank (myString):return not (myString and myString.strip())
def isNotBlank (myString):return bool(myString and myString.strip())

正如上面发布的,但有错误。

def isNoneOrEmptyOrBlankString (myString):if myString:if not myString.strip():return Trueelse:return Falsereturn False

我曾经写过类似于Bartek的回答和javascript启发的东西:

def is_not_blank(s):return bool(s and not s.isspace())

测试:

print is_not_blank("")    # Falseprint is_not_blank("   ") # Falseprint is_not_blank("ok")  # Trueprint is_not_blank(None)  # False

对于那些期望像apacheStringUtils.is空白或GuavaStrings.is空这样的行为的人:

if mystring and mystring.strip():print "not blank string"else:print "blank string"

测试空或空白字符串(较短的方式):

if myString.strip():print("it's not an empty or blank string")else:print("it's an empty or blank string")

这个怎么样?也许不是“最优雅的”,但看起来很完整和清晰:

if (s is None) or (str(s).strip()==""): // STRING s IS "EMPTY"...

当您通过行读取文件并想要确定哪一行为空时,请确保您将使用.strip(),因为“空”行中有新的行字符:

lines = open("my_file.log", "r").readlines()
for line in lines:if not line.strip():continue
# your code for non-empty lines

我发现硬编码(原文如此)“”每次检查空字符串都不太好。

干净的代码方法

这样做:foo == ""是非常糟糕的做法。""是一个魔法值。你永远不应该检查魔法值(通常称为神奇的数字

您应该做的是与描述性变量名进行比较。

描述性变量名

有人可能认为“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)和代码实现(我们实际上比较的是什么)

两者之间必须有一个关注点分离

回复@1290。抱歉,无法格式化注释中的块。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行为。

not str(myString)

对于空字符串,此表达式为True。非空字符串、无和非字符串对象都将产生False,注意对象可能会覆盖__str__以通过返回false sy值来阻止此逻辑。

如果你只是使用

not var1

不可能将布尔值False的变量与空字符串''区分开来:

var1 = ''not var1> True
var1 = Falsenot var1> True

但是,如果您在脚本中添加一个简单的条件,则会产生差异:

var1  = Falsenot var1 and var1 != ''> True
var1 = ''not var1 and var1 != ''> False

如果这对某人有用,这里是我构建的一个快速函数,用于将列表列表中的空字符串替换为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

这对于将列表列表发布到不接受某些字段空白的mysql数据库(在模式中标记为NN的字段)很有用。在我的例子中,这是由于复合主键)。

做到这一点的唯一真正可靠的方法是:

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使用字符串池(也称为字符串内部),如果它是内部的,它使用相同的字符串实例(参见此处:为什么使用'=='或'is'比较字符串有时会产生不同的结果?)。""在CPython中从一开始就是内部的

    身份检查的最大问题是String Internment(据我所知)没有标准化哪些字符串被嵌入。这意味着,理论上""不需要被嵌入,这取决于实现。

    此外,使用is比较字符串通常是一个非常邪恶的陷阱,因为它有时会正确工作,但在其他时候不会,因为字符串池遵循非常奇怪的规则。

  • 如果对象覆盖__bool__(),则依赖字符串的假可能不起作用。

唯一真正不能被愚弄的方法是开头提到的方法:"".__eq__(myString)。由于这显式调用空字符串的__eq__()方法,因此不能通过覆盖myString中的任何方法来愚弄它,并与str的子类一起工作。

这不仅是理论上的工作,而且实际上可能与实际使用相关,因为我之前看到框架和库子类化str并且使用myString is ""可能会在那里返回错误的输出。

也就是说,在大多数情况下,所有提到的解决方案都可以正常工作。这篇文章主要是学术工作。

我用 '', ' ', '\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()

如果需要,将其包装在方法定义中。

如果您不能完全确定您的输入实际上是一个字符串,我建议另外使用isinstance(object, classinfo)链接,如示例所示。

如果不是,列表或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>

下面是一个优雅的解决方案,适用于任何数量的空间。

def str_empty(s: str) -> bool:"""Strip white space and count remaining characters."""return len(s.strip()) < 1

>>> str_empty(' ')True

最明确的方法是:

if s == "":

好处:

  • 向程序员指示s的类型应该是什么。
  • ""不像x == 0那样是一个“硬编码”的神奇值。有些值是基本,不需要命名常量;例如x % 2来检查偶数。
  • 不能错误地指示任何false sy值(例如[])是空字符串。

考虑如何检查整数是否为0:

if x == 0:

没有应该做的是:

if not x:

整数和字符串都是原始值类型。为什么要区别对待它们?

如果您想检查字符串是否完全为空

if not mystring

这有效,因为空字符串是假的但是如果一个字符串只有空格,它将是true,所以你可能想要

if not mystring.strip()