一文了解Python流程控制

本文主要介紹 Python 的流程控制,包括 if、while、for 的用法以及一些注意事項等。閱讀本文預計需要 8 min。

1. 前言

計算機是按照一定的順序執行代碼,從而實現各種各樣的功能。編程就是將你的所思所想轉化爲一行行代碼,然後交給計算機來幫你執行。而要保證代碼按照你預想的順序執行,就需要你掌握代碼執行的流程。這也是我們看懂別人代碼的基礎。

溪流從源頭順流而下,有時可能會有分支,有時可能會有漩渦,最後匯入大海。程序也如溪流一樣,有一個程序入口,正常就按順序執行,有時會有分支結構,有時會有循環結構,最後有一個程序出口,程序結束。程序和現實往往驚人的相似,這是因爲程序就是對現實不斷的抽象,越來越接近我們現實,來幫助我們解決現實中的遇到的問題。

在 Python 中流程控制主要有順序執行、選擇執行、循環執行。順序執行指按照代碼的順序一行一行依次執行。選擇執行指一段代碼條件成立執行,否則不執行。循環執行指一段代碼多次執行。順序執行比較簡單,就不多說了。Python 中選擇執行主要是通過 if 條件語句控制的。另外 Python 中 try 異常錯誤處理語句也是一種選擇執行語句,只不過一般我們是用它處理錯誤異常的,這部分我們先不講解。Python 中循環語句主要是通過 while 語句 和 for 語句實現的。接下來我們將詳細介紹 if while for 語句的用法。主要內容:

  • if
  • if…else
  • if…elif…else
  • while
  • wile…else
  • for
  • for…else

2. 條件控制語句 if

if 語句是把我們現實中處理一件事物的所有可能性都列出來,並進行相應的處理。Python 中 if 語句的語法如下:

if expression:
    代碼塊1
(elif expression:
    代碼塊2
...)
[else:
    代碼塊3]

說明:expression 是條件表達式。代碼塊是英文 suite 翻譯而來,可以是一行或多行代碼,只要保證是相同的縮進。() 括起來的部分表示可以出現 0 次或者多次,常用於超過 2 個可能時。[] 部分代表可選,可以寫,也可以不寫。

程序會依次去判斷每一個 expression ,一旦 expression 爲真,就執行相應的 suite,然後跳過後面所有的 expression 判斷和 suite 的執行,如果所有的 expression 都不爲真的話,就會執行 else 語句的 suite

注意 if 可以單獨使用,但是elifelse 都不能單獨使用,需要和 if 配對使用。

if 用法測試如下:

print('用法一:只使用 if')
if 2 > 1:
    print('2 > 1')

print('用法二:使用 if...else 處理兩種可能,即單分支')
score = 66
if score > 60:
    print('恭喜你!合格啦!')
else:
    print('很遺憾,您未能通過本次考試...')

print('用法三:使用if...elif...elif...else 處理多種可能,即多分支')
math_score = 100
if math_score >= 90:
    print('天才!^_^')
elif math_score >= 80 and math_score < 90:
    print('優秀')
elif math_score >= 60 and math_score < 80:
    print('良好')
else:
    print('不及格...T_T')

結果輸出:
用法一:只使用 if
2 > 1
用法二:使用 if...else 處理兩種可能,即單分支
恭喜你!合格啦!
用法三:使用if...elif...elif...else 處理多種可能,即多分支
天才!^_^

如果我們暫時不知道怎麼處理一種情況,或者想直接忽略這種情況,那麼我們可以用 pass 語句來替換 suitepass 語句是一個佔位符,表示什麼也不做,以後你想到要怎麼操作,就用相應的代碼替換掉 pass 語句即可。

Python 中如果空列表出現在 expression,會被認爲是假,而不執行相應的 suite。如

if []:
    print('Python')

print('Python') 不會被執行,因爲 [] 爲假。

Python 中會被認爲是假的情況有:

  1. 被定義爲 None 或者 False 的常量。
  2. 表示 0 的數值:0, 0.0, 0j, Decimal(0), Fraction(0, 1)
  3. 序列或者集合爲空時:’’, (), [], {}, set(), range(0)

這裏需要注意一點,當我們用 andor 運算時,我們得到的結果是其中一個操作數,而不是 0 或 1。測試如下:

In [5]: 2 or 3
Out[5]: 2

In [6]: 0 or 3
Out[6]: 3

In [7]: 2 and 3
Out[7]: 3

In [8]: 0 and 3
Out[8]: 0

3. 循環控制語句 while

循環的重要性主要體現在以下兩個方面:

  1. 從編程角度考慮,循環可以避免代碼冗餘,減少工作量,增強代碼可讀性,比如:我們需要重複輸出某句話 10000 次,不用循環需要寫 10000 行 print(),使用循環 2 行代碼就可以搞定。

  2. 從用戶角度,循環可以提升用戶體驗,避免不必要的重複操作。比如:我們玩王者的時候,每打完一局,就得重新啓動王者,進行登錄等操作,那體驗就會很差。使用循環,我們就啓動一次,直到我們自己按退出,才終止遊戲。

Python 中 while 語句實現循環的語法如下:

while expression:
    suite_one
[else:
    suite_two]

說明:只要 expression 爲真,就執行 suite_one,再重複判斷 expression,直到 expression 爲假,終止循環。[] 部分爲可選部分,如果 suite_one 中沒有出現 break 提前終止循環,suite_two 就會被執行,從而結束循環。注意:即使 suite_one 一次也沒有執行,suite_two 也會執行,else 也是循環的一部分。

while...else 測試如下:

while 0:
    print('你好')
else:
    print('循環正常結束!')

結果輸出:
循環正常結束!

while 用法示例:

# 打印 10000 次 I love Python!
n = 10000
while n:  # 循環 10000 次後,n = 0, 爲假,循環終止
    print('I love Python!')
    n -= 1  # 等價於 n = n - 1
else:
    print('循環正常結束!')

結果輸出:
I love Python!
...
...
I love Python!
循環正常結束!

循環中可以使用 continuebreak 兩種語句.

  • continue:跳過本次循環剩下的代碼,去執行下一次循環的 expression 判斷。
  • break:終止循環,去執行循環後的第一句語句。

continuebreak 用法測試:

# 輸出 1-10 個數字
print('不使用 continue 和 break,輸出結果是:', end='')
n = 0
while n < 10:
    n += 1
    print(n, end=' ')  # end=' ' 是在 n 後面添加空格,默認是 end='\n', 即添加新行
else:
    print()  # 打印空行
    print('不使用 continue 和 break循環結束')

print('使用 continue 輸出結果是:', end='')
n = 0
while n < 10:
    n += 1
    if n == 9:
        continue
    print(n, end=' ')  # end=' ' 是在 n 後面添加空格,默認是 end='\n', 即添加新行
else:
    print()  # 打印空行
    print('使用 continue 結束')

print('使用 break 輸出結果是:', end='')
n = 0
while n < 10:
    n += 1
    if n == 9:
        break
    print(n, end=' ')  # end=' ' 是在 n 後面添加空格,默認是 end='\n', 即添加新行
else:
    print()  # 打印空行
    print('使用 continue 結束')

結果輸出:
不使用 continuebreak,輸出結果是:1 2 3 4 5 6 7 8 9 10
不使用 continuebreak循環結束
使用 continue 輸出結果是:1 2 3 4 5 6 7 8 10
使用 continue 結束
使用 break 輸出結果是:1 2 3 4 5 6 7 8
Process finished with exit code 0

我們可以看到,使用了 continue 會跳過輸出 9,但是還是會 執行 elsesuite;使用了 break 會直接終止循環,9 和 10 都不會輸出,同時也不會執行 elsesuite

循環雖然很強大,但它也有副作用,導致死循環的出現。下面就是一個死循環:

n = 0
while n < 10:
    if n == 9:
        continue
    n += 1
    print(n, end=' ')  # end=' ' 是在 n 後面添加空格,默認是 end='\n', 即添加新行

上面的代碼就會進入死循環,因爲 當 n == 9 時,執行 continue 語句,跳過後面的 n += 1print(n, end=' '),開始下一次的循環判斷。n = 9,所以 n < 10 成立,執行 if 語句,n == 9 成立,執行 continue 語句,又跳過後面的 n += 1print(n, end=' ')。 導致 n 一直是 9,n < 10 始終成立,從而進入死循環。

所以我們在寫循環時要注意以下幾點:

  1. 判斷條件初始值寫在循環體外面。
  2. 設置循環結束條件。
  3. 寫完循環後,最好測試一下,看看會不會導致死循環。

4. 循環控制語句 for

在 Python 中 for 語句也可以用於循環,它也是運用最多的循環方式,並且它的遍歷功能非常強大。遍歷是指把所有元素按順序一個一個訪問。for 語句可以遍歷序列的元素,比如字符串、元組、列表等,或者其他可迭代對象。可迭代對象是指可以用 for 去遍歷每一個元素的對象,比如 strtuplelist這些都屬於可迭代對象。

在 Python 中 for 的語法是:

for target_list in expression_list:
    suite_one
[else:
    suite_two]

說明:expression_list 只會被計算一次,並且生成一個可迭代對象。每次按順序從可迭代對象 expression_list 中取出一個值,並賦值給 target_list,然後執行 suite_one 代碼塊,不斷重複這個過程,直到 expression_list 爲空(即取完所有元素)或者引發 StopIteration 異常,最後會執行 else 部分的 suite_two,從而結束循環。[] 部分是可選的,可以不寫。

for 中我們也可以使用 continuebreak 語句,用法和在 while 中一樣,這裏不再展開。

for 用法示列:

# for 用法示例
print('使用 for 遍歷字符串:')
for i in 'Python':  # 遍歷字符串
    print(i, end=' ')  # end=' ' 在 i 後面添加一個空格

print('\n' + '使用 for 遍歷列表:')
for i in [1, 2, 3]:  # 遍歷列表
    print(i, end=' ')  # end=' ' 在 i 後面添加一個空格

print('\n' + '使用 for 遍歷元組:')
for i in (4, 5, 6):  # 遍歷元組
    print(i, end=' ')  # end=' ' 在 i 後面添加一個空格

print('\n' + '使用 for 遍歷可迭代對象 range(10):')
for i in range(10):  # 遍歷可迭代對象 range(10)
    print(i, end=' ')  # end=' ' 在 i 後面添加一個空格
else:  # 這個 else 匹配離它最近的 for
    print('\n' + 'for 遍歷可迭代對象 range(10) 結束!')

輸出結果:
使用 for 遍歷字符串:
P y t h o n
使用 for 遍歷列表:
1 2 3
使用 for 遍歷元組:
4 5 6
使用 for 遍歷可迭代對象 range(10)0 1 2 3 4 5 6 7 8 9
for 遍歷可迭代對象 range(10) 結束!

這裏出現range()函數。range()函數經常和 for 配合使用。
比如上面的 while 打印 10000 次 I love Python!,使用 range()for 配合,兩行代碼就可以搞定! 代碼如下:

# 打印 10000 次 I love Python!
for i in range(10000):
    print('I love Python!')

結果輸出:
I love Python!
...
...
I love Python!

注意for 去遍歷可迭代對象時,會生成一個內部計數器。這個內部計數器用於追蹤下一個要迭代的元素,並且會隨着每次迭代遞增。當我們用 for 遍歷一個可變序列,比如 list 時,如果在 suite 部分對 list 的部分進行了修改,可能會導致災難性的 bug。具體情況如下:

  1. 如果在遍歷 list 時,在 suite 部分刪除了該 list 中正在遍歷的元素或者它前面的元素,那麼當前遍歷元素的下一個元素將會被跳過。
  2. 如果在遍歷 list 時,在 suite 部分往該 list 中正在遍歷的元素之前添加一個元素,那麼當前遍歷元素的將會被再次遍歷。

情況一測試代碼如下:

# 移除列表中的所有 2
list_a = [1, 2, 2, 3, 4]
for i in list_a:
    if i == 2:
        list_a.remove(i)  # 移除一個 2
    print(i)
print(list_a)

輸出結果:
1
2
3
4
[1, 2, 3, 4]

可以發現,只有一個 2 被替換了。第 2 個 2 被跳過了。這個例子不是很好,只是爲了說明這個知識點。移除列表所有 2 更好的方法是用列表推導式 [i for i in list_a if i != 2]。使用列表推導式可以幫我們生成一個列表。

情況二測試代碼如下:

# 遍歷列表,當列表中出現 2 時,往列表頭部添加一個 4
list_a = [1, 2, 3]
for i in list_a:
    if i == 2:
        list_a.insert(0, 4)  # i == 2 時,在列表頭部添加一個 4
    print(i)
print(list_a)

結果輸出:
1
2
2
...

這段代碼會一直往 list_a 的頭部添加一個 4,直到計算機奔潰。

這種情況怎麼避免呢?我們可以通過切片創建拷貝來解決這個問題。
上面的代碼可以修改如下:

情況一修改後代碼:

# 移除列表中的所有 2
list_a = [1, 2, 2, 3, 4]
for i in list_a[:]:
    if i == 2:
        list_a.remove(i)
    print(i)
print(list_a)

結果輸出:
1
2
2
3
4
[1, 3, 4]

情況二修改後代碼:

# 遍歷列表,當列表中出現 2 時,往列表頭部添加一個 4
list_a = [1, 2, 3]
for i in list_a[:]:
    if i == 2:
        list_a.insert(0, 4)  # i == 2 時,在列表頭部添加一個 4
    print(i)
print(list_a)

輸出結果:
1
2
3
[4, 1, 2, 3]

所以,用 for 遍歷一個可變的可迭代對象時,如果要對可迭代對象進行修改操作,一定要利用切片進行拷貝,利用 for 遍歷拷貝。

學完這部分,我們對於 Python 中的流程控制已經基本掌握,能夠編寫並看懂一些簡單的 Python 代碼。後面將對 Python 中的函數進行總結。編程需要不斷地敲代碼,不斷地去寫才能慢慢的掌握。

5. 巨人的肩膀

  1. The Python 3.8 Tutorial

推薦閱讀:

  1. 編程小白安裝Python開發環境及PyCharm的基本用法
  2. 一文了解Python基礎知識
  3. 一文了解Python數據結構
  4. 一文了解Python流程控制
  5. 一文了解Python函數
  6. 一文了解Python部分高級特性
  7. 一文了解Python的模塊和包
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章