爲了完整起見,in
操作者可以被用作屬性成員資格的布爾運算符的測試。因此它可用於if..else
聲明(請參閱下面的完整文檔摘錄)。
當使用in
算子(例如,obj in container
)時,解釋器首先查找container
是否具有__contains__
方法。如果沒有,但如果container
定義__iter__
方法,蟒蛇隨後將遍歷包含在對象和測試平等的所有值即它基本上會執行類似
for value in container:
if value == obj:
return True
return False
最後,如果沒有方法定義,解釋器會查找__getitem__
方法來遍歷容器,並且仍然會測試與obj
的值相等的任何值。 您也可以看看the comparison operator documentation。
現在,在你的情況下,range([start], stop[, step])
功能[documentation]實際上返回一個列表(注意,這份名單確實不保持最後的元素,以便range(1, 5) == [1, 2, 3, 4]
),它定義了__contains__
方法:
>>> type(range(1, 10))
list
>>> hasattr(list, '__contains__')
True
>>> 4 in range(1, 10)
True
所以這完全有權寫x in range(1, 10)
。正如其他答案指出的,您的問題實際上是通過將輸入數據轉換爲整數解決的類型問題(因爲"3" == 3
爲False)。 然而,如果你只打算測試,如果輸入的值是否正確有界的,我會明確地建議你使用比較運算符
>>> if 1 <= x < 10:
... print 'ok'
... else:
... print 'ko'
,因爲它看起來更具可讀性和你是不是構建一個過時的列表,以便您會最大限度地減少你的內存佔用
注意避開列表的隱式建築,你可以使用xrange
函數返回一個迭代器,而不是一個列表,在這種情況下,作爲值懶洋洋地評估,xrange
沒有定義__contains__
方法,但它定義__iter__
方法,所以一切都會正常工作!
>>> type(xrange(1, 10))
xrange
>>> hasattr(xrange, '__contains__')
False
>>> hasattr(xrange, '__iter__')
True
>>> 4 in xrange(1, 10)
True
最後,這裏是從Python文檔中關於in
operator
的運營商,而不是在測試集合成員的提取物。如果x是集合s的成員,則x in s的計算結果爲true,否則返回false。 x不在s中返回s在x中的否定。集合成員資格測試傳統上與序列綁定;如果集合是一個序列並且包含與該對象相等的元素,則對象是集合的成員。但是,對於許多其他對象類型來說,支持成員測試而不是序列是有意義的。特別是,詞典(用於鍵)和集合支持成員資格測試。
對於列表和元組類型,當且僅當存在索引i以使x == y [i]爲真時,x中的y爲真。
對於Unicode和字符串類型,當且僅當x是y的子串時,y中的x爲真。等效的測試是y.find(x)!= -1。請注意,x和y不必是相同的類型;因此,'ab'中的''ab'將返回True。空字符串始終被認爲是任何其他字符串的子字符串,因此「abc」中的「」將返回True。
在2.3版本更改:以前,X被要求是長度爲1。
的連續字符串,它定義了__contains__
()方法用戶定義的類中,x在y爲真,當且僅如果y。 __contains__
(x)爲真。
對於沒有定義__contains__
()但定義了__iter__
()的用戶定義的類,如果在y上迭代時生成x = z的某個值z,則y中的x爲真。如果在迭代過程中引發異常,就像引發異常一樣。如果一個類定義了__getitem__
(),則y中的x爲真當且僅當存在非負整數索引i時,x == y [i] ,並且所有較低的整數索引不會引發IndexError異常。 (如果發生任何其他異常,就像引發該異常一樣)。
不被定義爲具有在逆真值的操作者
的運營商是並沒有測試對象標識:x是當且僅當x和y是相同的對象y是真。 x不是y產生逆真值。 [7]
注意,'範圍(1,5)'不包括數字5 – interjay