面向非程式設計師的 Python 2.6 布林表示式教程
這是一個布林表示式的簡單示例(您不必輸入它)
a = 6
b = 7
c = 42
print 1, a == 6
print 2, a == 7
print 3, a == 6 and b == 7
print 4, a == 7 and b == 7
print 5, not a == 7 and b == 7
print 6, a == 7 or b == 7
print 7, a == 7 or b == 6
print 8, not (a == 7 and b == 6)
print 9, not a == 7 and b == 6
輸出為
1 True 2 False 3 True 4 False 5 True 6 True 7 False 8 True 9 False
發生了什麼?程式包含一堆看起來奇怪的print語句。每個print語句都列印一個數字和一個表示式。數字用於幫助跟蹤我正在處理哪個語句。注意每個表示式最終都變成False或True。在 Python 中,false 也可以寫成 0,true 寫成 1。
以下幾行
print 1, a == 6
print 2, a == 7
分別打印出True和False,正如預期的那樣,因為第一個為真,第二個為假。第三個列印語句,print 3, a == 6 and b == 7,有點不同。運算子and表示如果前面和後面的語句都為真,則整個表示式為真,否則整個表示式為假。下一行,print 4, a == 7 and b == 7,顯示瞭如果and表示式的一部分為假,則整個表示式為假。and的行為可以總結如下
| 表示式 | 結果 |
|---|---|
true and true |
true |
true and false |
false |
false and true |
false |
false and false |
false |
請注意,如果第一個表示式為假,Python 不會檢查第二個表示式,因為它知道整個表示式為假。
下一行,print 5, not a == 7 and b == 7,使用了not運算子。not只是給出表示式的相反結果。(該表示式可以改寫為 print 5, a != 7 and b == 7)。以下是表格
| 表示式 | 結果 |
|---|---|
not true |
false |
not false |
true |
接下來的兩行,print 6, a == 7 or b == 7和print 7, a == 7 or b == 6,使用了or運算子。or運算子如果第一個表示式為真,或第二個表示式為真,或兩者都為真,則返回真。如果兩者都不為真,則返回假。以下是表格
| 表示式 | 結果 |
|---|---|
true or true |
true |
true or false |
true |
false or true |
true |
false or false |
false |
請注意,如果第一個表示式為真,Python 不會檢查第二個表示式,因為它知道整個表示式為真。這是有效的,因為or至少有一半表示式為真時就為真。第一部分為真,所以第二部分可以是假或真,但整個表示式仍然為真。
接下來的兩行,print 8, not (a == 7 and b == 6)和print 9, not a == 7 and b == 6,顯示了括號可以用來分組表示式,並強制先評估一部分。注意括號將表示式從假變為真。這是因為括號強制not應用於整個表示式,而不是僅僅應用於a == 7部分。
以下是如何使用布林表示式的示例
list = ["Life", "The Universe", "Everything", "Jack", "Jill", "Life", "Jill"]
# make a copy of the list. See the More on Lists chapter to explain what [:] means.
copy = list[:]
# sort the copy
copy.sort()
prev = copy[0]
del copy[0]
count = 0
# go through the list searching for a match
while count < len(copy) and copy[count] != prev:
prev = copy[count]
count = count + 1
# If a match was not found then count can't be < len
# since the while loop continues while count is < len
# and no match is found
if count < len(copy):
print "First Match:", prev
以下是輸出
First Match: Jill
該程式透過不斷檢查匹配項來工作,while count < len(copy) and copy[count] is not equal to prev。當count大於copy的最後一個索引或找到匹配項時,and不再為真,所以迴圈退出。if只是檢查確保while退出是因為找到了匹配項。
本例中使用了and的另一個“技巧”。如果您檢視and的表格,注意第三個條目是“false and won't check”。如果count >= len(copy)(換句話說,count < len(copy)為假),則不會檢視copy[count]。這是因為 Python 知道,如果第一個為假,則它們不可能都為真。這被稱為短路,在第二部分and可能會導致錯誤的情況下非常有用。我使用第一個表示式(count < len(copy))來檢查count是否是copy的有效索引。(如果您不相信我,請刪除匹配項“Jill”和“Life”,檢查它是否仍然有效,然後反轉count < len(copy) and copy[count] != prev的順序,使其成為copy[count] != prev and count < len(copy))。
當您需要一次檢查兩個或更多不同的事情時,可以使用布林表示式。
初學程式設計的人常犯的一個錯誤是對布林運算子工作方式的誤解,這源於 Python 直譯器讀取這些表示式的 방식。例如,在初步學習“and”和“or”語句後,人們可能會認為表示式x == ('a' or 'b')會檢查變數x是否等效於字串'a'或'b'中的一個。事實並非如此。要了解我的意思,請啟動與直譯器的互動會話,並輸入以下表達式
>>> 'a' == ('a' or 'b')
>>> 'b' == ('a' or 'b')
>>> 'a' == ('a' and 'b')
>>> 'b' == ('a' and 'b')
這將得到非直觀的結果
>>> 'a' == ('a' or 'b')
True
>>> 'b' == ('a' or 'b')
False
>>> 'a' == ('a' and 'b')
False
>>> 'b' == ('a' and 'b')
True
此時,and和or運算子似乎壞了。對於前兩個表示式,'a'等效於'a'或'b',而'b'則不是,這說不通。此外,'b'等效於'a'和'b',這也沒有道理。在檢查瞭解釋器對布林運算子的處理方式後,這些結果實際上完全符合您的要求,只是不符合您的預期。
當 Python 直譯器檢視or表示式時,它會取第一個語句,並檢查它是否為真。如果第一個語句為真,則 Python 會返回該物件的 value,而無需檢查第二個語句。這是因為對於or表示式,如果其中一個值為真,則整個表示式為真;程式不需要理會第二個語句。另一方面,如果第一個值被評估為假,則 Python 會檢查第二部分並返回該值。第二部分決定整個表示式的真值,因為第一部分為假。直譯器的這種“懶惰”被稱為“短路”,是許多程式語言中評估布林表示式的常用方法。
類似地,對於and表示式,Python 使用短路技術來加速真值評估。如果第一個語句為假,則整個表示式必須為假,因此它返回該值。否則,如果第一個值為真,則它會檢查第二個值並返回該值。
需要注意的是,布林表示式返回一個表示True或False的值,但 Python 認為許多不同的事物都有真值。要檢查任何給定物件x的真值,可以使用函式bool(x)來檢視其真值。以下是一些物件真值示例的表格
| True | False |
|---|---|
| True | False |
| 1 | 0 |
| 非零數字 | 字串 'None' |
| 非空字串 | 空字串 |
| 非空列表 | 空列表 |
| 非空字典 | 空字典 |
現在可以理解我們在之前測試那些布林表示式時得到的令人費解的結果了。讓我們看看直譯器在執行程式碼時的“看法”
第一種情況
>>> 'a' == ('a' or 'b') # Look at parentheses first, so evaluate expression "('a' or 'b')"
# 'a' is a nonempty string, so the first value is True
# Return that first value: 'a'
>>> 'a' == 'a' # the string 'a' is equivalent to the string 'a', so expression is True
True
第二種情況
>>> 'b' == ('a' or 'b') # Look at parentheses first, so evaluate expression "('a' or 'b')"
# 'a' is a nonempty string, so the first value is True
# Return that first value: 'a'
>>> 'b' == 'a' # the string 'b' is not equivalent to the string 'a', so expression is False
False
第三種情況
>>> 'a' == ('a' and 'b') # Look at parentheses first, so evaluate expression "('a' and 'b')"
# 'a' is a nonempty string, so the first value is True, examine second value
# 'b' is a nonempty string, so second value is True
# Return that second value as result of whole expression: 'b'
>>> 'a' == 'b' # the string 'a' is not equivalent to the string 'b', so expression is False
False
第四種情況
>>> 'b' == ('a' and 'b') # Look at parentheses first, so evaluate expression "('a' and 'b')"
# 'a' is a nonempty string, so the first value is True, examine second value
# 'b' is a nonempty string, so second value is True
# Return that second value as result of whole expression: 'b'
>>> 'b' == 'b' # the string 'b' is equivalent to the string 'b', so expression is True
True
因此,Python 在給出那些看似錯誤的結果時,實際上是在認真地執行任務。如前所述,重要的是要認識到布林表示式在評估時的返回值,因為它並不總是顯而易見的。
回到那些最初的表示式,以下是如何編寫它們,使它們的行為符合您的預期
>>> 'a' == 'a' or 'a' == 'b' True >>> 'b' == 'a' or 'b' == 'b' True >>> 'a' == 'a' and 'a' == 'b' False >>> 'b' == 'a' and 'b' == 'b' False
當這些比較被評估時,它們會以 True 或 False 的形式返回真值,而不是字串,因此我們得到了正確的結果。
password1.py
## This programs asks a user for a name and a password.
# It then checks them to make sure the user is allowed in.
name = raw_input("What is your name? ")
password = raw_input("What is the password? ")
if name == "Josh" and password == "Friday":
print "Welcome Josh"
elif name == "Fred" and password == "Rock":
print "Welcome Fred"
else:
print "I don't know you."
示例執行
What is your name? Josh What is the password? Friday Welcome Josh
What is your name? Bill What is the password? Money I don't know you.
編寫一個程式,讓使用者猜您的名字,但他們只有 3 次機會,否則程式會退出。
編寫一個程式,讓使用者猜您的名字,但他們只有 3 次機會,否則程式會退出。
print "Try to guess my name!"
count = 3
name = "Tony"
guess = raw_input("What is my name? ")
while count > 1 and guess != name:
print "You are wrong!"
guess = raw_input("What is my name? ")
count = count - 1
if guess != name:
print "You are wrong!" # this message isn't printed in the third chance, so we print it now
print "You ran out of chances."
quit
else:
print "Yes! My name is", name + "!"