" IN" Python 3.0中的空字符串运算符

时间:2016-05-15 01:07:53

标签: python string python-3.x

当我浏览Python 3的教程时,我遇到了以下内容:

>>> '' in 'spam'
True

我的理解是''等于没有空格。

当我尝试以下shell终端时,我得到下面显示的输出:

>>> '' in ' spam '
True

有人可以帮忙解释一下发生了什么吗?

3 个答案:

答案 0 :(得分:15)

''是空字符串,与""相同。空字符串是每个其他字符串的子字符串。

ab为字符串时,表达式a in b会检查ab的子字符串。也就是说,a中必须存在b的字符序列;必须有一个索引i,以便b[i:i+len(a)] == a。如果a为空,则任何索引i都满足此条件。

这并不意味着当您遍历b时,您将获得a。与其他序列不同,虽然for a in b生成的每个元素都满足a in b,但a in b并不意味着迭代a会产生b

因此'' in x"" in x对任何字符串x都返回True:

>>> '' in 'spam'
True
>>> "" in 'spam'
True
>>> "" in ''
True
>>> '' in ""
True
>>> '' in ''
True
>>> '' in ' ' 
True
>>> "" in " "
True

答案 1 :(得分:4)

string literal ''表示空字符串。这基本上是一个长度为零的字符串,不包含任何字符。

in运算符定义为for sequences,如果True的项目等于s,则返回“x,否则False”表达式x in s。对于一般序列,这意味着s中的一个项(通常可以使用迭代访问)等于测试元素x。但是对于字符串,in运算符具有子序列语义。当x in sx的子字符串时,s为真。

形式上,这意味着对于长度为x的子字符串n,必须有一个索引i,它满足以下表达式:s[i:i+n] == x

通过一个例子很容易理解:

>>> s = 'foobar'

>>> x = 'foo'
>>> n = len(x) # 3
>>> i = 0
>>> s[i:i+n] == x
True

>>> x = 'obar'
>>> n = len(x) # 4
>>> i = 2
>>> s[i:i+n] == x
True

在算法上,in运算符(或基础__contains__方法)需要做的是将i迭代到所有可能的值(0 <= i < len(s) - n)并检查是否条件适用于任何i

回顾空字符串,很明显为什么'' in s检查对于每个字符串s都为真:n为零,所以我们正在检查s[i:i];这是每个有效索引i的空字符串本身:

>>> s[0:0]
''
>>> s[1:1]
''
>>> s[2:2]
''

s作为空字符串本身甚至是正确的,因为序列切片被定义为在指定序列之外的范围时返回空序列(这就是为什么你可以s[74565463:74565469]开启短串)。

这就解释了为什么在将空字符串作为子字符串检查时,in的包含检查始终返回True。但即使您从逻辑上考虑它,您也可以看到原因:子字符串是字符串的一部分,您可以在另一个字符串中找到它。然而,空字符串可以在之间找到每两个字符。这就像你可以为一个数字添加无限量的零,你可以在字符串中添加无限量的空字符串,而无需实际修改该字符串。

答案 2 :(得分:1)

正如Rushy Panchal指出的,in包含运算符遵循集合理论约定,并假设空字符串是任何字符串的子字符串。

您可以尝试通过考虑以下因素来说服自己为什么这有意义:让s成为'' in s == False的字符串。然后'' in s[len(s):]最好是传递性错误(或者有s的子集包含'',但s不包含''等。但后来'' in '' == False,这也不是很好。因此,您无法选择任何字符串s,因此'' not in s不会产生问题。

当然,如果有疑问,请模拟它:

s = input('Enter any string you dare:\n')

print('' in '')
print(s == s + '' == '' + s)
print('' in '' + s)