# 單純遍歷的for語句names = ['Michael', 'Bob', 'Tracy']# 遍歷輸出names中的元素for name in names: print(name)for語句同樣可以實現dict的遍歷方法,如代碼清單2所示。dic = {'a': 1, 'b': 2, 'c': 3, 'd': 4}# 遍歷鍵值對print('key_value:', end = '')for key, value in dic.items(): print(key, value, sep = ':', end = ' ')# 遍歷鍵print('keys:', end = '')for key in dic.keys(): print(key, end = ' ')# 遍歷值print('values:', end = '')for value in dic.values(): print(value, end = ' ')key_value:a:1 b:2 c:3 d:4keys:a b c dvalues:1 2 3 4從代碼清單2可以看到,for語句中用於遍歷的「變量」不僅可以是Python默認的指代詞,也可以是常規的變量。和條件語句一樣,循環語句也可以使用嵌套,作用同樣是豐富程序的功能性。設計一個成績錄入系統,就必然要錄入姓名和課程這兩類信息,僅靠一層循環是無法實現的,可使用兩層循環結構,如代碼清單3所示。students = ['小明', '小紅']subjects = ['語文', '數學'] sum1 = []avg = []for i in students: print ('開始錄入%s的考試成績!'%i) sum = 0 for j in subjects: print('請輸入%s成績:'%j) score = int(input()) sum += score average = sum / 2 avg.append(average) sum1.append(sum)print(students, '的總分依次是', sum1, ',', '平均分依次是', avg)print('完成成績錄入!')開始錄入小明的考試成績!請輸入語文成績:97請輸入數學成績:90開始錄入小紅的考試成績!請輸入語文成績:89請輸入數學成績:100['小明', '小紅'] 的總分依次是 [187, 189] , 平均分依次是 [93.5, 94.5]完成成績錄入!while語句是Python中最常用的遞歸結構。區別於for循環,while循環結構包含條件判斷式,是一種條件循環,屬於當型循環。while語句最基本的形式包括一個位於頂部的布爾表達式,一個或多個屬於while代碼塊的縮進語句。也可以在結尾處包含一個else代碼塊,它與while代碼塊是同級的,組成while-else的形式。while語句的基本語法格式如下。while 條件表達式: 操作語句 1 操作語句 2 條件表達式:接收布爾表達式,表示判斷條件是否成立。無默認值操作語句:接收操作語句,表示執行一段代碼。無默認值執行while語句時,只要頂部的條件表達式返回真值,就一直執行while部分嵌套的遞歸代碼,當條件表達式返回假值時,不再執行操作語句,程序跳出while結構。sum = 0n = 99while n > 0: sum += n n -= 2print(sum)如果布爾表達式不帶有<、>、==、!=、in、not in等運算符,僅僅給出數值之類的條件,也是可以的。當while後寫入一個非零整數時,視為真值,執行循環體;寫入0時,視為假值,不執行循環體。也可以寫入str、list或任何序列,長度非零則視為真值,執行循環體;否則視為假值,不執行循環體。如果布爾表達式始終返回1,while語句就變成無限循環,如代碼清單5所示。# 布爾表達式為常數1,始終為真值while 1: print('循環')# 布爾表達式每次遞歸運算都為2,始終為真值x, y = 2, 1while x / y: print('循環') x = x * 2 y = y * 2運行代碼清單5,將會不斷列印出「循環」。代碼清單5展示了製造無限循環的兩種方式,既可以在while後寫入一個固定的真值,也可以寫入一個一直生成真值的表達式。要終止無限循環,可以使用快捷鍵Ctrl+C中斷循環的執行,也可以用循環終止語句,這將在下文中介紹。靈活地利用while語句中的布爾表達式及代入表達式的遞歸值,可以實現特別的功能,如代碼清單6所示。string = 'abcd'while string: print(string)# 該語句的遞歸計算是,每次從str的第2個字符開始截取 string = string[1:]代碼清單6包含一個自減迭代值,它並不通過明顯的運算符實現自減,而是利用索引法則,x變量一直從str中第2個值截取至結尾,每次都將位於str最前面的字符截取掉,最終只剩下一個字符時,再次截取就只有空的結果,布爾表達式返回0,循環終止。通過代碼清單5和代碼清單6可以看到,靈活地利用遞歸式,可以實現程序流向的控制。while循環同樣可以使用嵌套,嵌套的while循環實現成績錄入系統如代碼清單7所示。j = 1while j <= 2: sum = 0 i = 1 name = input('請輸入學生姓名:') while i <= 2: print ('請輸入第%d門的考試成績: '%i) sum += int(input()) i += 1 avg = sum / (i-1) print(name, '的平均成績是%d'%avg) j += 1print('學生成績輸入完成!')請輸入學生姓名:小明請輸入第1門的考試成績: 98請輸入第2門的考試成績: 88小明 的平均成績是93請輸入學生姓名:小紅請輸入第1門的考試成績: 65請輸入第2門的考試成績: 100小紅 的平均成績是82學生成績輸入完成!代碼清單7的第1層while語句用於錄入人名,第2層則在各人名下錄入多門成績,布爾表達式決定錄入的人數和課程數。在前兩節中,已經介紹了Python中的兩種循環語句。循環語句中還可以嵌入break、continue和pass語句,以靈活地改變流向,實現更多功能。在Python中,break語句用於終止循環語句的執行。使用該語句時,即使循環條件判斷為真,或序列未被完全遞歸,循環語句也會被立刻停止。break語句一般配合條件判斷使用,因為程序的終止必須是在某一條件被滿足時執行。break語句在for循環和while循環中的使用如代碼清單8所示。# break語句用於for循環string = "Python"for i in string:# 遍歷至string中的字符n時,不再執行else代碼塊 if i == 'n': break else: print("letter:{}". format(i))letter:Pletter:yletter:tletter:hletter:o
# break語句用於while循環counts = 0while True: print(counts) counts += 1# 滿足counts等於3時跳出循環,不再進入循環體 if counts == 3: break從代碼清單8可以看到,break語句用於for循環和while循環是有區別的。用於for循環時,只終止遍歷中某一次的循環體執行;用於while循環時,整個循環被終止。break只終止本層循環,如有多層嵌套的循環,在其中一層循環中寫入break,只在這層循環中生效,程序將跳到上一層循環中繼續運行,如代碼清單9所示。# 第1層循環,遍歷次數為2for i in range(2): print("%d" %i)# 第2層循環,遍歷次數為10 for j in range(10):# 使用break語句,j>1時不執行循環體 if j > 1: break print(j)001101在代碼清單9中,break語句在條件判斷式「if j>1:」後被使用,因此儘管j的指定遍歷次數為10,實際上遍歷只運行兩次。由於break語句只終止本層循環的運行,i依舊遍歷執行了兩次,而不是在第1次遍歷過程末尾終止。Python中的continue語句用於跳出當前循環,並執行下一次循環,而break跳出整層循環,兩者的功能具有明顯區別。如果一段代碼中包含continue語句,循環執行至continue處時,先忽略本次循環,在本層仍滿足條件的剩餘循環次數中繼續執行,不會終止這一層循環。實際上,如果在某一層的每次循環中都使用continue語句,就相當於使用break語句。列印一個數表,要不列印某些指定的數字,或只列印某類數,就可以使用continue語句跳過一些循環次數,該語句在for循環和while循環中都可以自由地使用,如代碼清單10所示。# 當i等於1或3時,跳過continue後的print語句for i in range(0,5): if i == 1 or i == 3: continue print(i)# 如果遇到偶數,跳過continue後的print語句counts = 0while counts < 10: counts += 1 if counts % 2 == 0: continue print(counts)break語句一旦用於嵌套循環中的第n層,該層循環會被終止,但在執行第n-1層循環時,仍會創造一個第n層循環並執行。continue語句同樣如此,只是仍會執行某一層的剩餘部分。因此,無論使用哪種循環終止語句,都只會影響使用終止語句的那一層循環,而不會干擾到其他層。continue語句用於循環的例子如代碼清單11所示。代碼清單11:continue語句用於嵌套循環結構# 第1層循環,遍歷次數為2for i in range(2): print("%d" %i)# 第2層循環,遍歷次數為5 for j in range(5):# 當j等於2或4時,不執行循環體 if j == 2 or j == 4: continue print(j)00131013pass是空語句,不做任何操作,只起到佔位的作用,其作用是為了保持程序結構的完整性。儘管pass語句不做任何操作,但如果暫時不確定要在一個位置放上什麼樣的代碼,可以先放置一個pass語句,讓代碼可以正常運行。pass語句並非循環或者條件語句的一部分,但與break、continue在代碼形式上有些類似。使用pass語句遍歷輸出str及數值計算,如代碼清單12所示。for element in "Python":# element為y時,不做任何操作,不會被輸出 if element == "y": pass else: print(element)counts = 0while counts < 5: counts += 1# i=3時,不執行循環體 if counts == 3: pass else: print(counts ** 2) 從代碼清單12可以看到,Python在「P」和「t」之間佔位,當循環遍歷到「y」時不做任何操作;當i等於3時,冪運算不執行,但不影響其他數值。上述兩個代碼如果在pass的位置缺失,程序將無法執行,因為判斷條件沒有給出相應的執行語句,會導致邏輯出錯。使用pass語句佔位,一方面為了讓程序正常執行,另一方面也是為了方便以後補充操作語句。推導式是可以從一個數據序列構建另一個新的數據序列的結構體,能夠非常簡潔地構造新的變量。列表推導式是其中最常用的類型。列表推導式又稱為列表解析式,是Python迭代機制的一種應用,也是一種高效創建列list的方式,可以動態地創建list。由於列表推導式必須用到遍歷循環,因此屬於一種特殊的循環。使用列表推導式時,需要將推導式寫在[]中。list中的元素可以來源於其他類型序列、可迭代對象或自建的滿足一定條件的序列。使用列表推導式的好處是代碼更加簡潔,實現效率更高。[操作語句 for變量 in 序列 if 條件表達式] 列表推導式可以不包含條件表達式,只做遍歷,生成list,如代碼清單13所示。vec = [-4, -2, 0, 2, 4]print([x * 2 for x in vec])[-8, -4, 0, 4, 8]
print([(x, x ** 2) for x in range(6)])[(0, 0), (1, 1), (2, 4), (3, 9), (4, 16), (5, 25)] 在代碼清單13中,除了列表推導式的簡單形式,還說明了列表推導式中可以使用多樣的函數和變量類型。另外,列表推導式中也可以包含條件語句,如代碼清單14所示。print([x for x in vec if x >= 0])列表推導式最大的優點還是簡潔,這需要與常規的編程方式進行對比。如代碼清單15所示,要創建一個平方數組成的list,這裡的兩種方式是等價的,但列表推導式的方式顯然代碼更加簡潔。squares = [] for x in range(10): squares.append(x ** 2) print(squares)[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
squares = [x ** 2 for x in range(10)] print(squares)[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]列表推導式中同樣可以實現嵌套循環,如代碼清單16所示。[(i, j) for i in range(0, 3) for j in range(0, 3)][(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
[(i, j) for i in range(0, 3) if i < 1 for j in range(0, 3) if j > 1]代碼清單16所示的列表推導式將兩個不同list中的元素整合到了一起。列表推導式中包含一對括號,在括號中有一個表達式,表達式後面緊跟一條for語句,然後是零條或多條for語句或if語句。通過for語句和if語句計算出表達式,結果作為新list的元素。本文摘編自《Python3智能數據分析快速入門》,經出版方授權發布。