2016-05-15 53 views
10

正如我在Python 3的經歷教程空字符串,我碰到了以下內容:「IN」運營商,在Python 3.0

>>> '' in 'spam' 
True 

我的理解是,''等於沒有空格。

當我嘗試下面的shell終端,我得到顯示它下面的輸出:

>>> '' in ' spam ' 
True 

是否有人可以幫忙解釋一下發生了什麼?

回答

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則返回true任何字符串x

>>> '' in 'spam' 
True 
>>> "" in 'spam' 
True 
>>> "" in '' 
True 
>>> '' in "" 
True 
>>> '' in '' 
True 
>>> '' in ' ' 
True 
>>> "" in " " 
True 
+1

如果空字符串,顧名思義,必須在以往其他字符串存在,爲什麼不迭代器集的一部分? I.E.因爲我在「垃圾郵件」中:print(i) – Brightlights

+0

@Brightlights這是一個有趣的問題。我可能錯誤地表述了這個 - 基本上,'b'中的'a'(用於字符串)檢查'a'的所有元素都在'b'中。因此,如果'a'是空的,它的每個元素(它們都不是元素)存在於任何'b'中。看到我更新的答案。 –

+1

@RushyPanchal:這不是檢查工作的方式。字符串中''a'檢查'a'是'b'的子字符串。對於檢查評估爲「真」,必須有一些索引'i',使得'b [i:i + len(a)] == a'。 (這與其他所有內置序列類型完全不同) – user2357112

4

string literal''代表空字符串。這基本上是一個長度爲零的字符串,其中不包含任何字符。

in的操作者被定義for sequences返回「True如果s項等於x,否則False」爲表達式x in s。對於一般序列,這意味着s中的其中一項(通常使用迭代可訪問)等於被測元素x。但對於字符串,in運算符具有子序列語義。所以x in s是真的,當xs的子字符串。

形式上,這意味着,對於一個子xn的長度,必須有一個索引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。但即使你在邏輯上考慮它,你也可以看到原因:一個子串是一個字符串的一部分,你可以在另一個字符串中找到它。然而,空字符串可以在之間找到每兩個字符。就像你如何向數字中添加無限多的零,你可以添加一個無限量的空字符串到一個字符串,而不需要實際修改那個字符串。

1

正如Rushy Panchal指出的,in包含運算符遵循set-theoretic convention並假定空字符串是任何字符串的子字符串。

您可以嘗試說服自己,爲什麼這是有道理的,考慮以下幾點:讓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)