Python入門 - 第 2 節(jié)課:控制流

目錄


1. 條件語句

  • If 語句

if語句是是一種條件語句,根據(jù)條件為 true 還是 false 運行或執(zhí)行相關(guān)代碼。下面是一個簡單的示例:

if phone_balance < 5:
    phone_balance += 10
    bank_balance -= 10
  • 第一行: if 語句以關(guān)鍵字if 開始,然后是要檢查的條件,在此例中是 phone_balance < 5,接著是英文冒號。條件用布爾表達式指定,結(jié)果為 TrueFalse。
  • 第二, 三行: 這行之后是一個條件為 true 時將執(zhí)行的縮進代碼塊。在此例中,僅在 phone_balance 小于 5 時才執(zhí)行使 phone_balance 遞增和使bank_balance 遞減的行。如果不小于 5,這個 if 塊中的代碼將被跳過。

?

  • If、Elif、Else

除了 if條件之外,if語句經(jīng)常還會使用另外兩個可選條件。例如:

if season == 'spring':
    print('plant the garden!')
elif season == 'summer':
    print('water the garden!')
elif season == 'fall':
    print('harvest the garden!')
elif season == 'winter':
    print('stay indoors!')
else:
    print('unrecognized season')
  1. ifif 語句必須始終以if條件開始,其中包含第一個要檢查的條件。如果該條件為 True,Python 將運行這個if塊中的縮進代碼,然后跳到 if 語句之后的剩余代碼。
  2. elifelif條件用來檢查其他條件(前提是if語句中之前的條件結(jié)果為 False)??梢詮氖纠锌闯?,可以使用多個elif 塊處理不同的情形。
  3. else:最后是else 條件,它必須位于if 語句的末尾。該條件語句不需要條件。如果if 語句中所有前面的語句結(jié)果都為False時,將運行 else 塊中的代碼。

?
?

2. 布爾表達式

If 語句有時候會使用更加復雜的條件布爾表達式。可能包括多個比較運算符、邏輯運算符,甚至包括算式。例如:

if 18.5 <= weight / height**2 < 25:
    print("BMI is considered 'normal'")

if is_raining and is_sunny:
    print("Is there a rainbow?")

if (not unsubscribed) and (location == "USA" or location == "CAN"):
    print("send email")

對于非常復雜的條件,你可能需要結(jié)合使用and、ornot。使用括號可以使運算符組合更清晰。

無論是簡單還是復雜的條件,if 語句中的條件都必須是結(jié)果為TrueFalse的布爾表達式,該值決定了if 語句中的縮進代碼塊是否執(zhí)行。

注意事項
1. 請勿使用 True 或 False 作為條件

# Bad example
if True:
    print("This indented code will always get run.")

雖然“True”是一個有效的布爾表達式,但不是有用的條件,因為它始終為 True,因此縮進代碼將始終運行。同樣,if False 也不應使用,該 if語句之后的語句將從不運行。

# Another bad example
if is_cold or not is_cold:
    print("This indented code will always get run.")

同樣,使用你知道將始終結(jié)果為 True 的條件(例如上述示例)也是毫無用途的。布爾表達式只能為 TrueFalse,因此is_coldnot is_cold將始終為 True,縮進代碼將始終運行。

2. 在使用邏輯運算符編寫表達式時,要謹慎
邏輯運算符 and、or 和 not 具有特定的含義,與字面英文意思不太一樣。確保布爾表達式的結(jié)果和你預期的一樣。

# Bad example
if weather == "snow" or "rain":
    print("Wear boots!")

這段代碼在 Python 中是有效的,但不是布爾表達式,雖然讀起來像。原因是 or 運算符右側(cè)的表達式 "rain" 不是布爾表達式,它是一個字符串。

3. 請勿使用 == True 或 == False 比較布爾變量
這種比較沒必要,因為布爾變量本身是布爾表達式。

# Bad example
if is_cold == True:
    print("The weather is cold!")

這是一個有效的條件,但是我們可以使用變量本身作為條件,使代碼更容易讀懂,如下所示。

# Good example
if is_cold:
    print("The weather is cold!")

如果你想檢查布爾表達式是否為 False,可以使用 not 運算符。

真假值測試
如果我們在if 語句中使用非布爾對象代替布爾表達式,Python 將檢查其真假值,判斷是否運行縮進代碼。默認情況下,Python 中對象的真假值被視為 True,除非在文檔中被指定為 False。

以下是在 Python 中被視為 False 的大多數(shù)內(nèi)置對象:

  • 定義為 false 的常量:NoneFalse
  • 任何數(shù)字類型的零:0、0.0、0j、Decimal(0)、Fraction(0, 1)
  • 空序列和空集合:””、()、[]、{}、set()、range(0)

示例:

errors = 3
if errors:
    print("You have {} errors to fix!".format(errors))
else:
    print("No errors to fix!")

在上述代碼中,errors 的真假值為 True,因為它是非零數(shù)字,因此輸出了錯誤消息。這是一個編寫 if 語句的簡練方式。

?
?

3. For 和 While 循環(huán)

For循環(huán)

Python 有兩種類型的循環(huán):for 循環(huán)和 while 循環(huán)。for 循環(huán)用來遍歷可迭代對象。

可迭代對象是每次可以返回其中一個元素的對象,包括字符串、列表和元組等序列類型,以及字典和文件等非序列類型。你還可以使用迭代器和生成器定義可迭代對象,
我們來了解下 for 循環(huán)的各個組成部分。請看下面的示例:

# iterable of cities
cities = ['new york city', 'mountain view', 'chicago', 'los angeles']

# for loop that iterates over the cities list
for city in cities:
    print(city.title())

For 循環(huán)的組成部分

  1. 循環(huán)的第一行以關(guān)鍵字 for 開始,表示這是一個 for 循環(huán)
  2. 然后是 iteration_variable in iterable,表示正在被遍歷的是可迭代的對象,并且用迭代變量表示當前正在被處理的可迭代對象的元素。在此示例中,迭代變量 city 在第一次迭代時將是“new york city”,在第二次迭代時將是“mountain view。
  3. for 循環(huán)頭部始終以英文冒號 : 結(jié)束。
  4. for 循環(huán)頭部之后的是在此 for 循環(huán)的每次迭代時運行的縮進代碼塊。在此塊中,我們可以使用迭代變量訪問當前正在被處理的元素的值。

你可以隨意命名迭代變量。常見模式是為迭代變量和可迭代對象指定相同的名稱,但是分別使用單復數(shù)形式(例如 'city' 和 'cities')

For循環(huán)創(chuàng)建和修改列表

  • 創(chuàng)建
    除了從列表中提取信息之外,你還可以使用 for 循環(huán)創(chuàng)建和修改列表。你可以在 for 循環(huán)的每次迭代時向新列表中添加元素,創(chuàng)建一個列表。如下所示。
# Creating a new list
cities = ['new york city', 'mountain view', 'chicago', 'los angeles']
capitalized_cities = []

for city in cities:
    capitalized_cities.append(city.title())

  • 修改
    修改列表稍微復雜些,需要使用新的函數(shù):range()。range() 是一個內(nèi)置函數(shù),用于創(chuàng)建不可變的數(shù)字序列。

    它有三個參數(shù),必須都為整數(shù)。 range(start=0, stop, step=1), Start是該序列的第一個數(shù)字,stop比該序列的最后一個數(shù)字大 1,step是該序列中每個數(shù)字之間的差。如果未指定的話,start默認為 0,step 默認為 1(即上述 =0=1)。

    因為 range 本身的輸出是一個 range 對象。我們可以通過將其轉(zhuǎn)換為列表或在 for 循環(huán)中遍歷它,查看 range 對象中的值集合。

    使用 range 函數(shù)為 cities 列表中的每個值生成索引。這樣我們便可以使用 cities[index] 訪問列表中的元素,以便直接修改 cities 列表中的值。

cities = ['new york city', 'mountain view', 'chicago', 'los angeles']

for index in range(len(cities)):
    cities[index] = cities[index].title()

雖然修改列表是 range 函數(shù)的一個用途,但是并非只有這一個用途。你將經(jīng)常使用 rangefor 循環(huán)重復某個操作一定的次數(shù)。

for i in range(3):
    print("Hello!")

?

While循環(huán)

For 循環(huán)是一種“有限迭代”,意味著循環(huán)主體將運行預定義的次數(shù)。這與“無限迭代”循環(huán)不同,無限迭代循環(huán)是指循環(huán)重復未知次數(shù),并在滿足某個條件時結(jié)束,while 循環(huán)正是這種情況。下面是一個 while 循環(huán)的示例。

card_deck = [4, 11, 8, 5, 13, 2, 8, 10]
hand = []

# adds the last element of the card_deck list to the hand list
# until the values in hand add up to 17 or more
while sum(hand)  <= 17:
    hand.append(card_deck.pop())

這個示例包含兩個函數(shù)。sum 返回列表中的元素之和,pop 是一個列表方法,它會從列表中刪除最后一個元素并返回該元素。

While 循環(huán)的組成部分

  • 第一行以關(guān)鍵字while開始,表示這是一個while 循環(huán)。
  • 然后是要檢查的條件。在此示例中是 sum(hand) <= 17
  • while 循環(huán)頭部始終以冒號 : 結(jié)束。
  • 該頭部之后的縮進部分是 while 循環(huán)的主體。如果 while 循環(huán)的條件為 true,該循環(huán)的主體將被執(zhí)行。每次運行循環(huán)主體時,條件將被重新評估。這個檢查條件然后運行循環(huán)的流程將重復,直到該表達式變成 false。

循環(huán)的縮進主體應該至少修改測試表達式中的一個變量。如果測試表達式的值始終不變,就會變成無限循環(huán)!

?
?

4. Break 和 Continue

有時候我們需要更精準地控制何時循環(huán)應該結(jié)束,或者跳過某個迭代。在這些情況下,我們使用關(guān)鍵字breakcontinue,這兩個關(guān)鍵字可以用于forwhile循環(huán)。

  • break 使循環(huán)終止
  • continue 跳過循環(huán)的一次迭代
    代碼示例
fruit = ['orange', 'strawberry', 'apple']
foods = ['apple', 'apple', 'hummus', 'toast']

fruit_count = 0
for food in foods:
    if food not in fruit:
        print('NOT a fruit')
        continue
# 執(zhí)行continue后, 后面的語句將不執(zhí)行, 進行下一次迭代.
    fruit_count += 1
    print('Found a fruit')  

?
?

5. Zip 和 Enumerate

zip 和 enumerate 是實用的內(nèi)置函數(shù),可以在處理循環(huán)時用到。

Zip

zip 返回一個(將多個可迭代對象組合成一個元組序列)的迭代器。每個元組都包含所有可迭代對象中該位置的元素。例如,

list(zip(['a', 'b', 'c'], [1, 2, 3])) 
#將輸出
 [('a', 1), ('b', 2), ('c', 3)]

正如 range()一樣,我們需要將其轉(zhuǎn)換為列表或使用循環(huán)進行遍歷以查看其中的元素。

你可以如下所示地用 for 循環(huán)拆封每個元組。

letters = ['a', 'b', 'c']
nums = [1, 2, 3]

for letter, num in zip(letters, nums):
    print("{}: {}".format(letter, num))

除了可以將兩個列表組合到一起之外,還可以使用星號拆封列表。

some_list = [('a', 1), ('b', 2), ('c', 3)]
letters, nums = zip(*some_list)

這樣可以創(chuàng)建正如之前看到的相同 lettersnums 列表。

Enumerate

enumerate 是一個會返回元組迭代器的內(nèi)置函數(shù),這些元組包含列表的索引。當你需要在循環(huán)中獲取可迭代對象的每個元素及其索引時,將經(jīng)常用到該函數(shù)。

letters = ['a', 'b', 'c', 'd', 'e']
for i, letter in enumerate(letters):
    print(i, letter)

這段代碼將輸出:

0 a
1 b
2 c
3 d
4 e

練習

將列表組合成字典

cast_names = ["Barney", "Robin", "Ted", "Lily", "Marshall"]
cast_heights = [72, 68, 72, 66, 76]

cast = dict(zip(cast_names, cast_heights))
print(cast)

輸出:
該輸出中的元素順序可能有變化,因為字典是無序的。

{'Lily': 66, 'Barney': 72, 'Marshall': 76, 'Ted': 72, 'Robin': 68}

拆封元組

cast = (("Barney", 72), ("Robin", 68), ("Ted", 72), ("Lily", 66), ("Marshall", 76))

names, heights = zip(*cast)
print(names)
print(heights)

輸出:

('Barney', 'Robin', 'Ted', 'Lily', 'Marshall')
(72, 68, 72, 66, 76)

用 Zip 進行轉(zhuǎn)置

data = ((0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11))

data_transpose = tuple(zip(*data))
print(data_transpose)

輸出:

((0, 3, 6, 9), (1, 4, 7, 10), (2, 5, 8, 11))

?
?

6. 列表推導式

在 Python 中,你可以使用列表推導式快速簡練地創(chuàng)建列表。

capitalized_cities = []
for city in cities:
    capitalized_cities.append(city.title())

可以簡寫為:

capitalized_cities = [city.title() for city in cities]

借助列表推導式,我們可以使用 for 循環(huán)用一步創(chuàng)建一個列表。

我們使用方括號[]創(chuàng)建列表推導式,括號里包含要對可迭代對象中的每個元素進行評估的條件。上述列表推導式對cities 中的每個元素city 調(diào)用 city.title(),以為新列表 capitalized_cities 創(chuàng)建每個元素。

列表推導式中的條件語句
還可以向列表推導式添加條件語句。在可迭代對象之后,你可以使用關(guān)鍵字 if 檢查每次迭代中的條件。

squares = [x**2 for x in range(9) if x % 2 == 0]

上述代碼將squares設(shè)為等于列表[0, 4, 16, 36, 64],因為僅在 x 為偶數(shù)時才評估 x 的 2 次冪。如果你想添加 else,將遇到語法錯誤。

squares = [x**2 for x in range(9) if x % 2 == 0 else x + 3]

如果你要添加 else,則需要將條件語句移到列表推導式的開頭,直接放在表達式后面,如下所示。

squares = [x**2 if x % 2 == 0 else x + 3 for x in range(9)]

列表推導式并沒有在其他語言中出現(xiàn),但是在 python 中很常見。

練習

提取名字

names = ["Rick Sanchez", "Morty Smith", "Summer Smith", "Jerry Smith", "Beth Smith"]

first_names = [name.split()[0].lower() for name in names]
print(first_names)

輸出:

['rick', 'morty', 'summer', 'jerry', 'beth']

按得分過濾姓名

scores = {
             "Rick Sanchez": 70,
             "Morty Smith": 35,
             "Summer Smith": 82,
             "Jerry Smith": 23,
             "Beth Smith": 98
          }

passed = [name for name, score in scores.items() if score >= 65]
print(passed)

輸出:
該輸出中的元素順序可能有變化,因為字典是無序的。

['Beth Smith', 'Summer Smith', 'Rick Sanchez']
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容