簡明Python教程·運算符與表達式&控制流
上一篇專欄


運算符與表達式
你所編寫的大多數(shù)語句(邏輯行)都包含了表達式(Expressions)。一個表達式的簡單例子 便是 2+3 。表達式可以拆分成運算符(Operators)與操作數(shù)(Operands)。
運算符(Operators)是進行某些操作,并且可以用諸如 + 等符號或特殊關(guān)鍵詞加以表達的 功能。運算符需要一些數(shù)據(jù)來進行操作,這些數(shù)據(jù)就被稱作操作數(shù)(Operands)。在上面的例子中 2 和 3 就是操作數(shù)。
運算符
接下來我們將簡要了解各類運算符及它們的用法。?
要記得你可以隨時在解釋器中對給出的案例里的表達式進行求值。例如要想測試表達式 2+3 ,則可以使用交互式 Python 解釋器提示符:
下面是可用運算符的速覽:
+ (加)
兩個對象相加。
3+5 則輸出 8 。 'a' + 'b' 則輸出 'ab' 。
- (減)
從一個數(shù)中減去另一個數(shù),如果第一個操作數(shù)不存在,則假定為零。
-5.2 將輸出一個負數(shù), 50 - 24 輸出 26 。?
* (乘)
給出兩個數(shù)的乘積,或返回字符串重復指定次數(shù)后的結(jié)果。
2 * 3 輸出 6 。 'la' * 3 輸出 'lalala' 。
** (乘方)
返回 x 的 y 次方。
3 ** 4 輸出 81 (即 3 * 3 * 3 * 3 )。
/ (除)
x 除以 y?
13 / 3 輸出 4.333333333333333 。
// (整除)
x 除以 y 并對結(jié)果向下取整至最接近的整數(shù)。
13 // 3 輸出 4 。
-13 // 3 輸出 -5 。
% (取模)
返回除法運算后的余數(shù)。
13 % 3 輸出 1 。 -25.5 % 2.25 輸出 1.5 。
<< (左移)
將數(shù)字的位向左移動指定的位數(shù)。(每個數(shù)字在內(nèi)存中以二進制數(shù)表示,即 0 和1)
2 << 2 輸出 8 。 2 用二進制數(shù)表示為 10 。
向左移 2 位會得到 1000 這一結(jié)果,表示十進制中的 8 。?
>> (右移)
將數(shù)字的位向右移動指定的位數(shù)。
11 >> 1 輸出 5 。
11 在二進制中表示為 1011 ,右移一位后輸出 101 這一結(jié)果,表示十進制中的 5 。
& (按位與)
對數(shù)字進行按位與操作。1
5 & 3 輸出 1 。
| (按位或) 對數(shù)字進行按位或操作。2
5 | 3 輸出 7 。
^ (按位異或)
對數(shù)字進行按位異或操作。3
5 ^ 3 輸出 6 。
~ (按位取反)4
x 的按位取反結(jié)果為 -(x+1)。
~5 輸出 -6 。有關(guān)本例的更多細節(jié)可以參?
閱:http://stackoverflow.com/a/11810203 。
< (小于)
返回 x 是否小于 y。所有的比較運算符返回的結(jié)果均為 True 或 False 。請注意這 些名稱之中的大寫字母。
5 < 3 輸出 False , 3 < 6 輸出 True 。
比較可以任意組成組成鏈接: 3 < 5 < 7 返回 True 。
> (大于)
返回 x 是否大于 y。
5 > 3 返回 True 。如果兩個操作數(shù)均為數(shù)字,它們首先將會被轉(zhuǎn)換至一種共同的 類型。否則,它將總是返回 False 。
<= (小于等于)
返回 x 是否小于或等于 y。
x = 3; y = 6; x<=y 返回 True 。
>= (大于等于)
返回 x 是否大于或等于 y。
x = 4; y = 3; x>=3 返回 True 。
== (等于)
比較兩個對象是否相等。
x = 2; y = 2; x == y 返回 True 。
x = 'str'; y = 'stR'; x == y 返回 False 。
x = 'str'; y = 'str'; x == y 返回 True 。
!= (不等于)
比較兩個對象是否不相等。
x = 2; y = 3; x != y 返回 True 。
not (布爾“非”)5
如果 x 是 Ture ,則返回 False 。如果 x 是 False ,則返回 True 。
x = Ture; not x 返回 False 。
and (布爾“與”)?6
如果 x 是 False ,則 x and y 返回 False ,否則返回 y 的計算值。
當 x 是 False 時, x = False; y = True; x and y 將返回 False 。在這一情境中, Python 將不會計算 y,因為它已經(jīng)了解 and 表達式的左側(cè)是 False ,這意味著整個 表達式都將是 False 而不會是別的值。這種情況被稱作短路計算(Short-circuit Evaluation)。
or (布爾“或”)7
如果 x 是 True ,則返回 True ,否則它將返回 y 的計算值。
x = Ture; y = False; x or y 將返回 Ture 。在這里短路計算同樣適用。
數(shù)值運算與賦值的快捷方式?
一種比較常見的操作是對一個變量進行一項數(shù)學運算并將運算得出的結(jié)果返回給這個變量, 因此對于這類運算通常有如下的快捷表達方式:
同樣也可寫作:
要注意到 變量 = 變量 運算 表達式 會演變成 變量 運算 = 表達式 。
求值順序?8
如果你有一個諸如 2 + 3 * 4 的表達式,是優(yōu)先完成加法還是優(yōu)先完成乘法呢?我們的高中 數(shù)學知識會告訴我們應該先完成乘法。這意味著乘法運算符的優(yōu)先級要高于加法運算符。
下面將給出 Python 中從最低優(yōu)先級(最少綁定)到最高優(yōu)先級(最多綁定)的優(yōu)先級表。這 意味著,在給定的表達式中,Python 將優(yōu)先計算表中位列于后的較高優(yōu)先級的運算符與表達 式。
為了保持完整,下表是從 Python 參考手冊 中引用而來。你最好使用圓括號操作符來對運算 符與操作數(shù)進行分組,以更加明確地指定優(yōu)先級。這也能使得程序更加可讀。你可以閱讀改 變運算順序來了解更多的細節(jié)。
lambda :Lambda 表達式
if - else :條件表達式?
or :布爾“或”?
and :布爾“與”?
not x :布爾“非”?
in, not in, is, is not, <, <=, >, >=, !=, == :比較,包括成員資格測試 (Membership Tests)和身份測試(Identity Tests)。
| :按位或?
^ :按位異或
& :按位與
<<, >> :移動
+, - :加與減
*, /, //, % :乘、除、整除、取余
+x, -x, ~x :正、負、按位取反
** :求冪
x[index], x[index:index], x(arguments...), x.attribute :下標、切片、調(diào)用、屬性引用
(expressions...), [expressions...], {key: value...}, {expressions...} :顯示綁定或數(shù) 組、顯示列表、顯示字典、顯示設(shè)置?
我們還沒有遇到的運算符將在后面的章節(jié)中加以解釋。?
在上表中位列同一行的運算符具有相同優(yōu)先級。例如 + 和 - 就具有相同的優(yōu)先級。
改變運算順序?
為了使表達式更加易讀,我們可以使用括號。舉個例子, 2 + (3 * 4) 自是要比 2 + 3 * 4 要更加容易理解,因為后者還要求你要了解運算符的優(yōu)先級。和其它的一切一樣,使用括號 同樣也要適度(而不要過度),同時亦應不要像 (2 + (3 * 4)) 這般冗余。
使用括號還有一個額外的優(yōu)點——它能幫助我們改變運算的順序。同樣舉個例子,如果你希 望在表達式中計算乘法之前應先計算加法,那么你可以將表達式寫作 (2 + 3) * 4 。
結(jié)合性?9
運算符通常由左至右結(jié)合。這意味著具有相同優(yōu)先級的運算符將從左至右的方式依次進行求 值。如 2 + 3 + 4 將會以 (2 + 3) +4 的形式加以計算。
表達式
案例(將其保存為 expression.py ):?
輸出:
它是如何工作的?
矩形的長度(Length)與寬度(Breadth)存儲在以各自名稱命名的變量中。我們使用它們并 借助表達式來計算矩形的面積(Area)與周長(Perimeter)。我們將表達式 length * breadth 的結(jié)果存儲在變量 area 中并將其通過使用 print 函數(shù)打印出來。在第二種情況 中,我們直接在 print 函數(shù)中使用了表達式 2 * (length + breadth) 的值。
同時,你需要注意到 Python是如何漂亮地打印出 輸出結(jié)果的。盡管我們沒有特別在 Area is 和變量 area 之間指定空格,Python 會幫我們加上所以我們就能得到一個整潔的輸出結(jié) 果,同時程序也因為這樣的處理方式而變得更加易讀(因為我們不需要在用以輸出的字符串 中考慮空格問題)。這便是一個 Python 是如何讓程序員的生活變得更加便捷美好的范例。
總結(jié)
我們已經(jīng)了解了如何使用運算符、操作數(shù)與表達式——這些是我們構(gòu)建任何程序的基本塊。 接下來,我們將看到如何在程序中善加利用這些語句。
. 按位與是針對二進制數(shù)的操作,指將兩個二進制數(shù)的每一位都進行比較,如果兩個相 應的二進位都為 1 則此位為 1,否則為 0。在本例中, 5 的二進制表達為 101 , 3 的 二進制表達為 11 (為補全位數(shù)進行按位操作寫作 011 ),則按位與操作后的結(jié)果為 001 ,對應的十進制數(shù)為 1 。 ?
. 按位或是針對二進制數(shù)的操作,指將兩個二進制數(shù)的每一位都進行比較,如果兩個相 應的二進位有一個為 1 則此位為 1,否則為 0。在本例中, 101 與 011 進行按位或操 作后的結(jié)果為 111 ,對應十進制數(shù)為 7 。 ?
. 按位異或是針對二進制數(shù)的操作,指將兩個二進制數(shù)的每一位都進行比較,如果兩個 相應的二進位不同則此位為 1,相同為 0。在本例中, 101 與 011 進行按位異或操作 的結(jié)果為 110 ,對應十進制數(shù)為 6 。 ?
. 按位取反也稱作“按位取非”或“求非”或“取反”,沈潔元譯本譯作“按位翻轉(zhuǎn)”,是針對二進 制數(shù)的操作,指將兩個二進制數(shù)的每一二進位都進行取反操作, 0 換成 1 , 1 換成 0 。受篇幅與學識所限,本例具體原理不在此處贅述。讀者只需按照給出的公式記憶即 可。 ?
. 原文作 Boolean NOT。 ??
. 原文作 Boolean AND。 ?
. 原文作 Boolean OR。 ?
. 原文作 Evaluation Order。 ?
. 原文作 Associativity,沈潔元譯本譯作“結(jié)合規(guī)律”。 ??

控制流?
截止到現(xiàn)在,在我們所看過的程序中,總是有一系列語句從上到下精確排列,并交由 Python 忠實地執(zhí)行。如果你想改變這一工作流程,應該怎么做?就像這樣的情況:你需要程序作出 一些決定,并依據(jù)不同的情況去完成不同的事情,例如依據(jù)每天時間的不同打印出 '早上好' 'Good Morning' 或 '晚上好' 'Good Evening'?
正如你可能已經(jīng)猜測到的那番,這是通過控制流語句來實現(xiàn)的。在 Python 中有三種控制流語 句—— if for 和 while 。?
if 語句
if 語句用以檢查條件:如果 條件為真(True),我們將運行一塊語句(稱作 if-block 或 if 塊),否則 我們將運行另一塊語句(稱作 else-block 或 else 塊)。其中 else 從句是可選 的。
案例(保存為 if.py ):
輸出:?
它是如何工作的?
在這個程序中,我們根據(jù)用戶猜測的數(shù)字來檢查這一數(shù)字是否是我們所設(shè)置的。我們將變量 number 設(shè)為任何我們所希望的整數(shù),例如 23 。然后,我們通過 input() 函數(shù)來獲取用戶 的猜測數(shù)。所謂函數(shù)是一種可重復使用的程序。我們將在下一章詳細討論它。
我們?yōu)閮?nèi)置的 input 函數(shù)提供一串打印到屏幕上的字符串并等待用戶的輸入。一旦我們輸入 了某些內(nèi)容并按下鍵盤上的 enter 鍵, input() 函數(shù)將以字符串的形式返回我們所輸入的 內(nèi)容。然后我們通過 int 將這個字符串轉(zhuǎn)換成一個整數(shù)并將其儲存在變量 guess 中。實際 上, int 是一個類(Class),但你現(xiàn)在你所需要知道的就是你可以使用它將一串字符串轉(zhuǎn) 換成一個整數(shù)(假設(shè)這個字符串的文本中含有一個有效的整數(shù))。
接下來,我們將用戶提供的猜測數(shù)與我們所選擇的數(shù)字進行對比。如果它們相等,我們就打 印一條成功信息。在這里要注意到我們使用縮進級別來告訴 Python 哪些語句分別屬于哪個 塊。這便是為什么在 Python 中縮進如此重要。我希望你能夠堅持“縮進一致”的原則,你能做 到吧?
另外需要注意的是 if 語句在結(jié)尾處包含一個冒號——我們借此向 Python 指定接下來會有 一塊語句在后頭。
然后,我們檢查猜測數(shù)是否小于我們選擇的數(shù)字,如果是,我們將告訴用戶他們必須猜一個 更高一些的數(shù)字。在這里我們使用的是 elif 語句,它們實際上將兩個相連的 if else-if else 語句合并成一句 if-elif-else 語句。這能夠使程序更加簡便,并且可以減少所需要的 縮進量。
elif 和 else 同樣都必須有一個冒號在其邏輯行的末尾,后面跟著與它們相應的語句塊 (當然,別忘了恰當?shù)目s進)。
你可以在 if 塊的 一個 if 語句中設(shè)置另一個 if 語句,并可以如此進行下去——這被稱作 嵌套的 if 語句。
要記住 elif 和 else 部分都是可選的。一個最小規(guī)模且有效的 if 語句是這樣的:
當 Python 完整執(zhí)行了 if 語句及與其相關(guān)的 elif 和 else 子句后,它將會移動至包含 if 語句的代碼塊的下一句語句中。在本例中,也就是主代碼塊(程序開始執(zhí)行的地方), 其下一句語句就是 print('Done') 語句。在完成這些工作后,Python 會發(fā)現(xiàn)已行至程序末尾 并宣告工作的完成。
盡管這是一個非常簡單的程序,我也一直在其中指出你應該注意的事情。所有的這些都可算 是簡單易懂(對于那些具有 C/C++ 背景的人來說是相當簡單易懂)。不過在開始時它們還是 可能會不斷吸引你的注意,不斷地去在意它們。但經(jīng)過一些更豐富的操作后你就會習慣它們 及其中的邏輯,它們對于你來說將會成為“自然而然”的事情。
針對 C/C++ 程序員的提示?
Python 中不存在 switch 語句。你可以通過使用 if..elif..else 語句來實現(xiàn)同樣的事 情(在某些情況下,使用一部?字典?能夠更快速地完成)。
while 語句?
while 語句能夠讓你在條件為真的前提下重復執(zhí)行某塊語句。 while 語句是 循環(huán) (Looping) 語句的一種。 while 語句同樣可以擁有 else 子句作為可選選項。
案例(保存為 while.py ):
輸出:
它是如何工作的?
在這一程序中,我們依舊通過猜數(shù)游戲來演示,不過新程序的優(yōu)點在于能夠允許用戶持續(xù)猜 測直至他猜中為止——而無需像我們在上一節(jié)中所做的那樣,每次猜測都要重新運行程序。 這種變化恰到好處地演示了 while 語句的作用。
首先我們將 input 與 if 語句移到 while 循環(huán)之中,并在 while 循環(huán)開始前將變量 running 設(shè)置為 True 。程序開始時,我們首先檢查變量 running 是否為 True ,之后再執(zhí) 行相應的 while 塊。在這一代碼塊被執(zhí)行之后,將會重新對條件進行檢查,在本例中也就是 running 變量。如果它依舊為 True ,我們將再次執(zhí)行 while 塊,否則我們將繼續(xù)執(zhí)行可選 的 else 塊,然后進入到下一個語句中。
else 代碼塊在 while 循環(huán)的條件變?yōu)?False 時開始執(zhí)行——這個開始的時機甚至可能是 在第一次檢查條件的時候。如果 while 循環(huán)中存在一個 else 代碼塊,它將總是被執(zhí)行, 除非你通過 break 語句來中斷這一循環(huán)。
True 和 False 被稱作布爾(Boolean)型,你可以將它們分別等價地視為 1 與 0 。
針對 C/C++ 程序員的提示?
你可以在 while 循環(huán)中使用 else 從句。
for 循環(huán)?
for...in 語句是另一種循環(huán)語句,其特點是會在一系列對象上進行迭代(Iterates),意即 它會遍歷序列中的每一個項目。我們將在后面的序列(Sequences)章節(jié)中了解有關(guān)它的更 多內(nèi)容?,F(xiàn)在你所需要的就是所謂隊列就是一系列項目的有序集合。?
案例(保存為 for.py ):
輸出:
它是如何工作的?
在這一程序中,我們打印了一序列的數(shù)字。我們通過內(nèi)置的 range 函數(shù)生成這一數(shù)字序列。
?在這里我們所要做的事情是提供兩個數(shù)字,而 range 將會返回一序列的數(shù)字,從第一個數(shù)字 開始,至第二個數(shù)字結(jié)束。舉個例子, range(1,5) 將輸出序列 [1, 2, 3, 4] 。在默認情況 下, range 將會以 1 逐步遞增。如果我們向 range 提供第三個數(shù)字,則這個數(shù)字將成為逐 步遞增的加數(shù)。同樣舉個例子來說明, range(1,5,2) 將會輸出 [1, 3] 。要記住這一序列擴 展直到第二個數(shù)字,也就是說,它不會包括第二個數(shù)字在內(nèi)。
另外需要注意的是, range() 每次只會生成一個數(shù)字,如果你希望獲得完整的數(shù)字列表,要 在使用 range() 時調(diào)用 list() 。例如下面這樣: list(range(5)) ,它將會返回 [0, 1, 2, 3, 4] 。有關(guān)列表的詳細解釋將會在 《數(shù)據(jù)結(jié)構(gòu)》一章 呈現(xiàn)。
然后 for 循環(huán)就會在這一范圍內(nèi)展開遞歸—— for i in range(1,5) 等價于 for i in [1, 2, 3, 4] ,這個操作將依次將隊列里的每個數(shù)字(或是對象)分配給 i ,一次一個,然后以 每個 i 的值執(zhí)行語句塊。在本例中,我們這一語句塊所做的就是打印出這些值。?
同樣要記住, else 部分是可選的。當循環(huán)中包含他時,它總會在 for 循環(huán)結(jié)束后開始執(zhí) 行,除非程序遇到了 break 語句。
另一個需要注意的地方是 for...in 能在任何隊列中工作。在這里,我們有的是通過內(nèi)置的 range 函數(shù)生成的一串數(shù)字列表,但總體來說我們可以包含任何類型對象的隊列!我們將會 在后面的章節(jié)詳細解釋這一觀念。
?針對 C/C++/Java/C# 程序員的提示?
Python 中的 for 循環(huán)和 C/C++ 中的 for 循環(huán)可以說是完全不同。C# 程序員會注意 到 Python 中的 for 循環(huán)與 C# 中的 foreach 循環(huán)相似。Java 程序員則會注意到它同 樣與 Java 1.5 中的 for (int i : IntArray) 無甚區(qū)別。?
在 C/C++ 中,如果你希望編寫 for (int i = 0; i < 5; i++) ,那么在 Python 你只需要 寫下 for i in range(0,5) 。正如你所看到的,Python 中的 for 循環(huán)將更加簡單,更具表現(xiàn)力且更不容易出錯。
break 語句
? break 語句用以中斷(Break)循環(huán)語句,也就是中止循環(huán)語句的執(zhí)行,即使循環(huán)條件沒有 變更為 False ,或隊列中的項目尚未完全迭代依舊如此。
?有一點需要尤其注意,如果你的 中斷 了一個 for 或 while 循環(huán),任何相應循環(huán)中的 else 塊都將不會被執(zhí)行。
?案例(保存為 break.py ):
輸出:
它是如何工作的?
在本程序中,我們重復地接受用戶的輸入內(nèi)容并打印出每一次輸入內(nèi)容的長度。我們通過檢 查用戶輸入的是否是 quit 這一特殊條件來判斷是否應該終止程序。我們通過中斷循環(huán)并轉(zhuǎn) 進至程序末尾來結(jié)束這一程序。
輸入字符串的長度可以通過內(nèi)置的 len 函數(shù)來找到。
記住, break 語句同樣可以適用于 for 循環(huán)。?
Swaroop 的詩意 Python?
我所使用的輸入內(nèi)容是一首我所寫的小詩:?
continue 語句
continue 語句用以告訴 Python 跳過當前循環(huán)塊中的剩余語句,并繼續(xù)該循環(huán)的下一次迭代。
案例(保存為 continue.py ):
輸出:
它是如何工作的?
在本程序中,我們接受來自用戶的輸入內(nèi)容,但是只有在輸入的字符串其長至少 3 字符我們 才會對其進行處理。為此,我們使用內(nèi)置的 len 函數(shù)和來獲取字符串的長度,如果其長度小 于 3,我們便通過使用 continue 語句跳過代碼塊中的其余語句。否則,循環(huán)中的剩余語句將 被執(zhí)行,并在此處進行我們所希望的任何類型的處理。
要注意 continue 語句同樣能用于 for 循環(huán)。
總結(jié)
我們已經(jīng)了解了三種控制流語句—— if , while 和 for ——及其相關(guān)的 break 與 continue 語句是如何工作的。這些語句是 Python 中一些最常用的部分,因此,習慣去使用 它們是必要的。?
接下來,我們將了解如何創(chuàng)建并使用函數(shù)。

下一篇專欄
