天天看點

“笨辦法”學Python 3基礎篇 - 資料容器與程式結構“笨辦法”學Python 3基礎篇系列文章前言4.1 程式邏輯結構-分支 if、elif、else4.2 程式邏輯結構-循環 for 和 while4.3 更複雜的清單操作結語

“笨辦法”學Python 3基礎篇系列文章

“笨辦法”學Python 3基礎篇 第一部分-列印與輸入

“笨辦法”學Python 3基礎篇 第二部分-檔案操作

“笨辦法”學Python 3基礎篇 第三部分-函數

“笨辦法”學Python 3基礎篇 第四部分-資料容器與程式結構

“笨辦法”學Python 3基礎篇 第五部分-面向對象的類

“笨辦法”學Python 3基礎篇 第六部分-項目骨架與自動測試

“笨辦法”學Python 3基礎篇 第七部分-搭建簡易的網站

第四部分 資料容器與程式結構

  • “笨辦法”學Python 3基礎篇系列文章
  • 前言
  • 4.1 程式邏輯結構-分支 if、elif、else
    • 4.1.1 文法格式
    • 4.1.2 讓我們來做一個簡易口算訓練器
      • 4.1.2.1 随機數 - random用法
      • 4.1.2.2 生成随機運算符 - if + else + random
      • 4.1.2.3 運算函數
      • 4.1.2.4 綜合
  • 4.2 程式邏輯結構-循環 for 和 while
    • 4.2.1 for + 清單
    • 4.2.2 while + 清單
    • 4.2.3 挑戰一個更複雜的口算訓練器
  • 4.3 更複雜的清單操作
  • 結語

前言

上個禮拜一直在忙本人學校教學大綱修訂的任務,自3月23日至3月30日止,期間耗費了較多精力,是以本來計劃的上周要繼續總結假期學習内容的博文也來不及寫了。昨天又是上課又是開會,回家還得教育孩子,實在是沒精力敲打鍵盤了。今天終于得空,繼續進行Python3 假期學習内容的總結。

本篇主要是總結常用的程式邏輯結構-分支和循環,并将分支、循環和資料容器-清單相結合進行總結。

4.1 程式邏輯結構-分支 if、elif、else

在學C語言或者Verilog HDL語言時,進行算法級的描述常用到的邏輯控制結構為分支結構(也叫做條件結構)和循環結構。分支結構用于進行條件的判斷,進而根據判斷結果做出決定,以 if、elif、else 的使用最常見。循環結構則是用于邏輯的疊代,資料的周遊,以 for、while 的使用最常見。如果我們不想隻局限于列印和輸入,那麼就必然會用到這兩個程式邏輯結構來設計更複雜的功能。

4.1.1 文法格式

不同于C語言,在Python3 中分支的基本文法結構為:

“笨辦法”學Python 3基礎篇 - 資料容器與程式結構“笨辦法”學Python 3基礎篇系列文章前言4.1 程式邏輯結構-分支 if、elif、else4.2 程式邏輯結構-循環 for 和 while4.3 更複雜的清單操作結語

分支結構以 if 開頭,後接布爾表達式和 : 号。行尾冒号的作用是告訴Python接下來你要建立一個新代碼塊,下接的代碼塊必修進行縮進,以此來告訴Python這些代碼處于該段代碼快中,與建立函數時相同。根據布爾表達式的真或假,選擇運作 if 代碼塊還是 elif 代碼塊。如果所有情況都不滿足,則執行預設的 else 代碼塊。

4.1.2 讓我們來做一個簡易口算訓練器

現在,我們可以用分支結構來解決一個簡單的問題:

設計一個簡易整數口算訓練機,提供口算習題并能夠判斷口算結果是否正确

分析這個問題,這樣一個簡單的口算訓練機,需要實作如下功能:

  1. 用随機數生成口算的操作數;
  2. 用随機數和分支結構生成運算符(加法和減法);
  3. 用函數求出正确答案;
  4. 提問與等待解答;
  5. 分支結構判斷口算結果,做出對錯決定。

4.1.2.1 随機數 - random用法

為了生成随機數,我們需要import一個叫做 random 的子產品,這是一個Python安裝時就有的系統子產品,不需要額外安裝擴充包。然後通過random子產品去調用不同的随機數生成方法,常用的為:

  • random.random() : 傳回生成的一個實數,在[0,1)範圍内;
  • random.uniform(num1,num2) : 傳回生成的一個實數,範圍在[num1,num2)之間;
  • random.randint(num1,num2): 傳回生成的一個整數,範圍為num1到num2。

來看這樣一段代碼:

import random

print(random.random())
print(random.random()*100)
print(random.uniform(100,101))
print(random.randint(0,100))
           

第一行代碼為引入random子產品,後面四行代碼分别實作生成[0,1)的随機實數、生成[0,100)的随機實數、生成[100, 101)的随機實數、生成0-100的随機整數。在PowerShell運作後,結果為:

“笨辦法”學Python 3基礎篇 - 資料容器與程式結構“笨辦法”學Python 3基礎篇系列文章前言4.1 程式邏輯結構-分支 if、elif、else4.2 程式邏輯結構-循環 for 和 while4.3 更複雜的清單操作結語

4.1.2.2 生成随機運算符 - if + else + random

在掌握了random子產品生成随機數的方法後,我們就需要将生成的随機數按照數值大小劃分出兩個部分,即[0,50)和[50,100)這兩個部分。每個部分作為一個判斷條件,執行減法函數或加法函數的調用,具體的分支結構(僞代碼)為:

if 随機數處于[0,50) :

調用加法函數add

else :

調用減法函數sub

具體的實作代碼為

import random

def gen():
	op1 = random.randint(0, 100)
	op2 = random.randint(0, 100)
	op3 = random.random()*100
	if op3 < 50:
		return add(op1, op2)
	elif op3 >= 50 and op1 >= op2:
		return sub(op1, op2)
	else:
		return sub(op2, op1)
           

在這段代碼中,我們通過 gen() 這個函數來負責随機數和随機運算符的生成。op1 和 op2是運算時的兩個操作數,通過op3來判斷生成加法還是減法。如果op3小于50,則調用加法函數實作 op1 + op2;如果op3大于等于50且op1大于op2,傳回sub(op1,op2), 實作 op1 - op2; 否則傳回sub(op2, op1), 實作 op2 - op1。

4.1.2.3 運算函數

運用“笨辦法”學Python 3基礎篇 第三部分-函數

中的設計方法,加法和減法函數功能為:

  • print 目前算式
  • 等待輸入口算結果
  • 分支結構判斷結果
  • print 運算結果

具體的代碼為:

from sys import exit

def add(augend, addend):
	print(f"{augend} + {addend} = ", end = "")
	result = int(input())
	if result == augend + addend:
		print(f"The result is true.")
		exit(0)
	else:
		print(f"The result is false.")
		exit(0)

def sub(augend, subend):
	print(f"{augend} - {subend} = ", end = "")
	result = int(input())
	if result == augend - subend:
		print(f"The result is true.")
		exit(0)
	else:
		print(f"The result is false.")
		exit(0)
           

為了計算成功後,能夠退出腳本, 我們引入了exit子產品。通過使用exit(0)來正常退出程式,回到PowerShell。

4.1.2.4 綜合

完成了随機數生成、随機運算符和運算函數後,剩下的就是綜合了。綜合後的代碼為:

from sys import exit
import random

def gen():
	op1 = random.randint(0, 100)
	op2 = random.randint(0, 100)
	op3 = random.random()*100
	if op3 < 50:
		return add(op1, op2)
	elif op3 >= 50 and op1 >= op2:
		return sub(op1, op2)
	else:
		return sub(op2, op1)

def add(augend, addend):
	print(f"{augend} + {addend} = ", end = "")
	result = int(input())
	if result == augend + addend:
		print(f"The result is true.")
		exit(0)
	else:
		print(f"The result is false.")
		exit(0)

def sub(augend, subend):
	print(f"{augend} - {subend} = ", end = "")
	result = int(input())
	if result == augend - subend:
		print(f"The result is true.")
		exit(0)
	else:
		print(f"The result is false.")
		exit(0)

print("Welcome! Are you ready to start a math test?")
print("Y/N", end='')
decide = input('> ')
if (decide == 'Y'):
    gen()
else:
    print("Coward!")
           

當然,這裡少不了用分支結構設計一下對話方式,通過輸入Y來執行gen()函數,通過N來輸出字元串。運作PowerShell後得到的結果為

“笨辦法”學Python 3基礎篇 - 資料容器與程式結構“笨辦法”學Python 3基礎篇系列文章前言4.1 程式邏輯結構-分支 if、elif、else4.2 程式邏輯結構-循環 for 和 while4.3 更複雜的清單操作結語

4.2 程式邏輯結構-循環 for 和 while

循環結構是另一種常用的邏輯控制結構。常用到的是for和while。

4.2.1 for + 清單

在開始使用for循環之前,我們需要在某個位置存放循環的結果,也就是需要一個資料的容器。最好的方法是使用清單。清單的定義非常簡單,以 [ 開頭打開清單,然後寫下要放入清單的東西,用逗号隔開,就跟函數的參數一樣,最後需要用右括号 ] 表明清單結束。例如:

  • hairs = [‘brown’, ‘blond’, ‘red’]

如果想要周遊hairs這個清單的所有元素,此時我們就需要用到for循環了。for循環的基本文法結構為:

for 變量 in 序列:

代碼

else:

代碼

這裡的序列可以是清單或者字元串, else後面的是可選項。下面我們來看如何周遊hairs這個清單,并列印出每個元素。代碼如下:

hairs = ['brown', 'blond', 'red']

for color in hairs:
	print(f"Your hair is {color}!")

for number in range(3):
	print(f"My hair is {hairs[number]}, too!")
           

在這段代碼中,第一個for循環将hairs清單中的元素在每次循環時依次指派給了color,實作了清單元素的周遊。第二個for循環中序列則采用了range(3)函數,實作了0,1,2三個整數的周遊。每周遊一個整數,number變量就指派為該整數并從hairs清單中切片出對應元素。PowerShell運作結果如圖所示。

“笨辦法”學Python 3基礎篇 - 資料容器與程式結構“笨辦法”學Python 3基礎篇系列文章前言4.1 程式邏輯結構-分支 if、elif、else4.2 程式邏輯結構-循環 for 和 while4.3 更複雜的清單操作結語

4.2.2 while + 清單

如果要使用while循環來實作,則首先我們得了解while循環的基本文法結構:

while(布爾條件):

代碼1

else:

代碼2

當布爾條件為真時,執行代碼1;否則執行else的代碼塊。當然else是可以省略的。

用while代替for循環來編列hairs清單遇到最主要的問題是需要找出布爾條件。可以采用計數器+清單元素的個數來作為布爾條件實作循環的結束。具體代碼如下:

hairs = ['brown', 'blond', 'red']
count = 0
while(count < len(hairs)):
	print(f"Her hair is {hairs[count]}!")
	count += 1
           

在該段代碼中,定義了一個計數器count,每周遊清單中的一個元素,累計加1。通過len()獲得了清單元素的個數。當計數器count等于清單元素個數時跳出循環。PoweShell運作結果為:

“笨辦法”學Python 3基礎篇 - 資料容器與程式結構“笨辦法”學Python 3基礎篇系列文章前言4.1 程式邏輯結構-分支 if、elif、else4.2 程式邏輯結構-循環 for 和 while4.3 更複雜的清單操作結語

4.2.3 挑戰一個更複雜的口算訓練器

之前我們的口算訓練程式每次隻能做一次運算。現在我們可以用邏輯循環結構來為口算訓練程式添加如下功能:

  1. 使用者可以設定每次訓練的口算題數;
  2. 用循環結構重複生成随機口算式子并計分;
  3. 列印出最終正确率,并退出程式

具體的實作代碼為:

from sys import exit
import random

def gen():
	op1 = random.randint(0, 100)
	op2 = random.randint(0, 100)
	op3 = random.random()*100
	if op3 < 50:
		return add(op1, op2)
	elif op3 >= 50 and op1 >= op2:
		return sub(op1, op2)
	else:
		return sub(op2, op1)

def add(augend, addend):
	print(f"{augend} + {addend} = ", end = "")
	result = int(input())
	if result == augend + addend:
		return 1
	else:
		return 0

def sub(augend, subend):
	print(f"{augend} - {subend} = ", end = "")
	result = int(input())
	if result == augend - subend:
		return 1
	else:
		return 0

print("Welcome! Are you ready to start a math test?")
print("Y/N", end='')
decide = input('> ')
if (decide == 'N'):
     print("Coward!")
     exit(0)
else:
	print("How many exercises do you want to try?", end='')
	count = int(input('> '))
	score = 0 
while count != 0:
    score += gen()
    count -= 1
print(f"Your final test score is {score}.")   
exit(0)
           

在這段代碼中,我們對add()和sub()函數做了稍微的修改,不再讓它們列印出每次計算的結果,而是傳回1或者是0。在程式控制段,修改了條件分支的順序,避免了while循環和if條件分支程式塊的文法錯誤。同時,通過count變量實作了口算題的計數,通過while循環實作了正确率score的累計加1。循環結束條件則為計數器遞減為0。最後列印出正确率結果并啟用exit(0)退出程式。

PoweShell的運作結果為:

“笨辦法”學Python 3基礎篇 - 資料容器與程式結構“笨辦法”學Python 3基礎篇系列文章前言4.1 程式邏輯結構-分支 if、elif、else4.2 程式邏輯結構-循環 for 和 while4.3 更複雜的清單操作結語

4.3 更複雜的清單操作

在4.1和4.2節中,我們已經簡單接觸到了清單,實作了清單元素的周遊。當然還可以對清單的元素做很多操作, 比如添加和彈出元素等,具體可參考清單list。

接下來,我們将運用清單添加元素來繼續解決口算練習器的問題:

使用者能夠浏覽上一次口算訓練做錯的題目和自己的答案

為了實作這一功能,我們需要建立一個清單mistakes,用來存儲錯題和正确的答案。然後通過for 循環,周遊mistakes清單中的每個錯題,并列印出來。具體的代碼為:

from sys import exit
import random

def gen():
	op1 = random.randint(0, 100)
	op2 = random.randint(0, 100)
	op3 = random.random()*100
	if op3 < 50:
		return add(op1, op2)
	elif op3 >= 50 and op1 >= op2:
		return sub(op1, op2)
	else:
		return sub(op2, op1)

def add(augend, addend):
	print(f"{augend} + {addend} = ", end = "")
	result = int(input())
	if result == augend + addend:
		return 1
	else:
		mistakes.append(f'{augend} + {addend} = {result}, the right answer is {augend + addend}' )
		return 0

def sub(augend, subend):
	print(f"{augend} - {subend} = ", end = "")
	result = int(input())
	if result == augend - subend:
		return 1
	else:
		mistakes.append(f'{augend} - {subend} = {result}, the right answer is {augend - subend}')
		return 0

print("Welcome! Are you ready to start a math test?")
print("Y/N", end='')
decide = input('> ')
if (decide == 'N'):
     print("Coward!")
     exit(0)
else:
	mistakes = []
	print("How many exercises do you want to try?", end='')
	count = int(input('> '))
	success = count
	score = 0 
while count != 0:
    score += gen()
    count -= 1
if score == success:
	print(f"Congratulations! You got all exercises right!")
	exit(0)
else:
	print(f"Your final test score is {score}.")  
	print("Here is your wrong record: ") 
	for var in mistakes:
		print(var)	 
exit(0)
           

代碼的修改部分主要為定義了一個名為mistakes的空清單,并在add和sub函數中采用了mistakes.append實作了清單元素的添加(預設從清單末尾添加,具體用法可參考清單list)。結果為:

“笨辦法”學Python 3基礎篇 - 資料容器與程式結構“笨辦法”學Python 3基礎篇系列文章前言4.1 程式邏輯結構-分支 if、elif、else4.2 程式邏輯結構-循環 for 和 while4.3 更複雜的清單操作結語

結語

資料容器更重要的一個概念是:字典。這篇文章由于中途有事,又寫了兩天,沒有來得及寫字典。後面要加快進度,把字典放在後續總結,并多以案例來總結學到的基本程式設計理論,這樣能更快速的消化。