2014-01-06 25 views
1
def test_string_membership(): 
    assert False == 'c' in 'apple' 
    assert True == 'a' in 'apple' 
    assert True == 'app' in 'apple' 

p.s: - 我是一個Python初學者,無法找出什麼是錯的。我運行代碼時斷言失敗。我的斷言失敗了這段python的代碼

+1

即使您獲得了優先權(例如,括號),這不是Pythonic,並且過於複雜。你幾乎不應該把事情與「真」或「假」相比。如果你想測試是否屬實,只要做'如果有事';如果你想測試它是否是假的,「如果不是東西」。 – abarnert

+0

此外,您可能從C或相關語言中學到的「將常量放在任何比較的左側」規則對於Python來說並不是一個好規則。在C語言中,當你的意思是「if(foo == 0)」時,意外地寫了'if(foo = 0)',而不是''if(0 = foo)'給了你一個明顯的錯誤。但在Python中,如果spam = 0已經給你一個明顯的錯誤,所以這是不必要的。按照自然順序「如果我檢查的東西等於我期望的值」而不是後退,會使得代碼更具可讀性(至少適用於習慣於Python代碼的人)。 – abarnert

+0

謝謝@abarnert會做:) – Yasasvee

回答

5

False == 'c' in 'apple'不被解釋爲

False == ('c' in 'apple') 

但是,

(False == 'c') and ('c' in apple) 

becaue的comparison chaining


要得到你想要的,明確地放上括號。

False == ('c' in 'apple') 

或更優選使用in/not in

def test_string_membership(): 
    assert 'c' not in 'apple' 
    assert 'a' in 'apple' 
    assert 'app' in 'apple' 
+0

具體來說,'=='和'in'具有相同的優先級。具有相同優先級的運算符在表達式中從左到右進行解釋。 http://docs.python.org/2/reference/expressions.html#operator-precedence –

+0

謝謝@falsetru :) – Yasasvee

+0

@paxdiablo:這絕對不是神奇地轉換爲'str'那樣。如果是這樣,'123'中的'2'將是'真'而不是'TypeError'。 – abarnert

3

你有比較鏈接,即對待Python語法問題:

x < y < z 

爲:

x < y and y < z. 

在你的情況,這意味着表達False == 'c' in 'apple'被視爲:

(False == 'c') and ('c' in 'apple') 

這兩者都是錯誤的,因此導致asserti上。有關Python 3比較鏈接的詳細信息,請參閱here

因此,爲了避免這種chianing的方式是使表達明確的,喜歡的東西:

assert False == ('c' in 'apple') 
assert True == ('a' in 'apple') 
assert True == ('app' in 'apple') 

,或者甚至更好,因爲有true/false比較是很少一個好主意:

assert 'c' not in 'apple' # or "not('c' in 'apple')" if you're testing 'in'. 
assert 'a' in 'apple' 
assert 'app' in 'apple' 
+0

謝謝@paxdiablo :) – Yasasvee

1

在這種情況下,您可以使用()。有更好的方法來做你正在嘗試的東西。

def test_string_membership(): 
    assert False == ('c' in 'apple') 
    assert True == ('a' in 'apple') 
    assert True == ('app' in 'apple') 

這是因爲優先。詳細瞭解Python docs

in, not in, is, is not, <, <=, >, >=, <>, !=, ==處於相同的優先級別。因此Python將評估從左到右

False == 'c' in 'apple' 

+0

我不會說你__必須用'()'''在'apple'=='assert'c'assert'會做OP所期望的。或者,正如falsetru所示,'assert'c'不在'apple'' –

+0

謝謝@christian :) – Yasasvee

1

使用括號應該解決這個問題作爲

def test_string_membership(): 
    assert False == ('c' in 'apple') 
    assert True == ('a' in 'apple') 
    assert True == ('app' in 'apple') 
+0

謝謝@Bharadwaj :) – Yasasvee

2

相反,其他的答案,這裏發生了什麼不運算符優先級但是comparison chaininga == b in c意味着(a == b) and (b in c),就像a < b < c意味着(a < b) and (b < c)。然而,在任何一種情況下,結果都是一樣的,這就是你不想做的事情。正如在其他答案和評論中指出的那樣,可以使用括號修正它,或者更好的是,根本不使用相等比較,只是在做assert 'c' not in 'apple'

你可以看到,這是比較鏈接通過一個稍微不同的例子:

>>> 'a' == 'a' in 'ab' 
True 

這顯然是錯誤的,不管優先朝哪個方向走,但由於'a' == 'a''a' in 'ab'都是真的,那是真實的。