5-1 串列(list)的操作
我們之前有說明過我們通常會用變數來儲存資料,但有時我們資料量很大的時候,不可能會用很多變數儲存,在操作上會非常不方便,如此就需要有一種資料型態特別用來存取大量資料,在Python中稱為串列(list),在其他程式語言則稱為陣列(Array)。list的語法用[]表示,[1,2,3]則代表此串列儲存3筆數據,data=[1,2,3]則是將串列[1,2,3]指定給data變數,也就是說data代表[1,2,3]。以下我們說明list的一些基本操作方法:
程式碼
#list的基本操作方式
numList=[-1,-2,-3,0,1,2,3] #list元素皆為數值
strList=["Jacky","John","Jimmy"] #list元素皆為字串
print("numList第1的元素:{}".format(numList[0]))
print("numList第2的元素:{}".format(numList[1]))
print("strList第3的元素:{}".format(strList[2]))
print("numList倒數第1的元素:{}".format(numList[-1]))
print("strList倒數第2的元素:{}".format(strList[-2]))
print("numList第2~4的元素形成的子串列:{}".format(numList[1:4]))
print("numList倒數第5~最後一個元素形成的子串列:{}".format(numList[-5:]))
print("numList第1~7的元素取出間隔為2的元素形成的子串列:{}".format(numList[0:7:2]))
Python畫面
5-2 串列的進階操作
接下來我們將介紹一些常用的串列相關函數,有助於大數據的整理與分析。
程式碼
#list的進階操作
list1=[2]
list2=list1*10
print("10個2的串列:{}".format(list2))
print("list2的長度(元素個數):{}".format(len(list2)))
print("="*30)
list3=[-2,10,2,-4,7,0,1,2,7,7]
print("list3的最大元素:{}".format(max(list3)))
print("list3的最小元素:{}".format(min(list3)))
print("list3中2的索引值:{}".format(list3.index(2)))
print("list3中第2個2的索引值:{}".format(list3.index(2,list3.index(2)+1)))
print("list3中7的個數:{}".format(list3.count(7)))
print("list3中11的個數:{}".format(list3.count(11)))
print("="*30)
list4=["a","b","c","d","e"]
list5=["Jacky","John","Jimmy"]
list4.append("@")
print("在list4的最後面插入元素@:{}".format(list4))
list4.insert(3,"#")
print("在list4的第4個位置插入#:{}".format(list4))
list4.extend(list5)
print("在list4的最後面插入list5:{}".format(list4))
list4.pop()
print("移除list4的最後一個元素:{}".format(list4))
list4.remove("@")
print("移除list4中@的元素:{}".format(list4))
list4.remove("%")
print("移除list4中%的元素:{}".format(list4))
del list4[2:5]
print("移除list4中位置2到位置4的元素:{}".format(list4))
del list4[0::2]
print("list4位置0到最後一個元素中每次間隔2將元素移除:{}".format(list4))
print("="*30)
list6=["a","b","c","d","e","d","f"]
list7=[-2,10,2,-4,7,0,1,2,7,7]
list6.reverse()
print("list6反轉:{}".format(list6))
list7.sort(reverse=True)
print("list7由大排到小:{}".format(list7))
Python畫面
我們已經了解了串列進階的函數,我們可以利用這些函數,來進行簡單的文本分析,也就是說,給定一篇文章,計算每個單字出現的次數,我們現在就來操作這個例子,英文短文範例如下:
Enjoy that uniquenesss1. You do not have to pretend in order to seem more like someone else. You do not have to lie to hide the parts of you that are not like what you see in anyone else.
You were meant to be different. Nowhere, in all of history, will the same things be going on in anyone’s mind, soul and spirit as are going on in yours right now.
程式碼
#簡易文本分析
artic='''Enjoy that uniquenesss1. You do
not have to pretend in order to seem more like someone else. You do not have to
lie to hide the parts of you that are not like what you see in anyone else.
You were meant to be different. Nowhere, in
all of history, will the same things be going on in anyone’s mind, soul and
spirit as are going on in yours right now.
'''
artic=artic.lower() #將所有單字都變為小寫
artic=artic.replace("\n",
"") #移除\n符號
artic=artic.replace(",",
"") #移除,符號
artic=artic.replace(".",
"") #移除.符號
vocabulary_list=artic.split(" ") #將文章切割為單字串列
print("切割後的單字串列:{}".format(vocabulary_list))
quire=input("請輸入要查詢的單子...")
print("您查詢的單字為{},出現的個數為{}".format(quire,vocabulary_list.count(quire)))
Python畫面
程式碼
#資料表表示
datatable=[["王曉明",98,60,71],["陳大文",100,100,98],["張安安",60,70,72]]
print("{:6s}{:6s}{:6s}{:6s}".format("姓名","國文","英文","數學"))
print("{0[0]:6s}{0[1]:<8d}{0[2]:<8d}{0[3]:<8d}".format(datatable[0]))
print("{0[0]:6s}{0[1]:<8d}{0[2]:<8d}{0[3]:<8d}".format(datatable[1]))
print("{0[0]:6s}{0[1]:<8d}{0[2]:<8d}{0[3]:<8d}".format(datatable[2]))
Python畫面
5-4 元組(tuple)操作
元組的結構與串列完全相同,但主要差異點在於元組的資料不能被修改而串列可以,故元組也被稱為不可修改的串列。之前說過串列主要用[]表示,而元組則是用()表示。
程式碼
#tuple的操作
tuple1=(-2,10,2,-4,7,0,1,2,7,7)
print("tuple8的元素個數:{}".format(len(tuple1)))
print("tuple8中的7的個數:{}".format(tuple1.count(7)))
print("tuple8第3個元素:{}".format(tuple1[2]))
print("tuple8第2~5個元素形成的子元組:{}".format(tuple1[1:5]))
Python畫面
我們剛剛說tuple與list的差異在於tuple不可改變內容而list可以,以下就舉幾個簡單例子說明一下,在下面的例子中,我們嘗試修改tuple中元素的值與在tuple中新增新的值,結果都會得到error message:
程式碼
#tuple與list的差異(1)
list_test=[1,2,3,4,5]
tuple_test=(1,2,3,4,5)
list_test[0]=100 #將list_test第一個元素修改為100
print("修改後的list_test:{}".format(list_test))
tuple_test[0]=100 #將tuple_test第一個元素修改為100
print("修改後的tuple_test:{}".format(tuple_test))
Python畫面
程式碼
#tuple與list的差異(2)
list_test=[1,2,3,4,5]
tuple_test=(1,2,3,4,5)
list_test.append(100) #將list_test新增元素100
print("修改後的list_test:{}".format(list_test))
tuple_test.append(100) #將tuple_test新增元素100
print("修改後的tuple_test:{}".format(tuple_test))
Python畫面
5-5 for迴圈的基礎操作
迴圈是程式撰寫中非常重要的一個技巧,他可以快速執行重複性的工作,使得不需要寫很多結構相同的程式碼,在程式的維護上也相對容易許多,但對於初學者在學習程式時,要讓程式重複執行相同的工作,第一直覺就是將程式碼一直複製,雖然這種作法一樣可以達到相同的結果,但是屬於沒有效率的程式撰寫方式,因為程式碼若需要一點修改,可能每一行程式都要修改,這將導致程式維護不易。在迴圈的操作上,最常見的就是for迴圈與while迴圈,後續我們會好好介紹這兩個迴圈的撰寫方式與差異。一開始我們先介紹for迴圈,for迴圈的程式結構如下:
for 變數 in 串列:
程式區塊
我們用以下簡易範例說明:
程式碼
#for迴圈操作(1)
import time
for i in [1,2,3,4,5]:
print("現在取得的i的值為{}".format(i))
print("正要返回for敘述取得下一個i值")
time.sleep(1) #程式執行延遲1秒
print("<<串列中的值已皆拜訪過一次,結束迴圈!>>")
Python畫面
說明一下這個簡易的例子,for迴圈在執行時,會拜訪串列中每個元素,而元素會被指定給變數(這裡我們把變數命名為i),然後進入程式區塊執行程式,這邊要特別注意,程式區塊必須要縮排,否則會出現錯誤訊息。這邊因為程式過於簡單,執行速度會非常快就結束(不到一秒),所以為了讓讀者感受for迴圈的工作,我們在一開始先引進一個time套件(語法:import time),想藉由time套件中的time.sleep(秒數)這個函數,讓程式執行時中間有延遲的效果,讀者可更清楚for迴圈的執行模式。
大多數學習for迴圈時,第一個挑戰的題目就是,計算1+2+3+…+10,我們都知道是55,但如何用撰寫程式的方式得到答案,卻是一個學習程式過程中必經之路,通常初學者會很有耐心的寫1+2+3+4+5+6+7+8+9+10,然後執行程式得到正確答案,但這種寫法就是我們所說的沒有效率的寫法,今天如果將1加到10改成1加到100還是要這樣寫嗎? 讀者可以思考一下? 我們以下用for迴圈解決這個問題。
程式碼
#for迴圈操作(2)
Sum=0
for i in [1,2,3,4,5,6,7,8,9,10]:
Sum=Sum+i
print("<<迴圈結束!>> Sum值為{}".format(Sum))
Python畫面
這裡用到將Sum值更新的寫法,Sum=Sum+i,第一次i取得為1時,進到程式區塊後Sum+i就是0+1,結果為1在指定回Sum,所以這時候Sum被更新為1(1)了;第二次i取得為2時,進到程式區塊後Sum+i就是1+2,結果為3在指定回Sum,所以這時候Sum又被更新為3(1+2)了; 第三次i取得為3時,進到程式區塊後Sum+i就是3+3,結果為6(1+2+3)再指定回Sum,所以這時候Sum再次被更新為6了,依此類推,最後Sum值會被更新到55,也就是1+2+3+…+10的結果。
但相信有讀者會發現,如果1+2+3+…+100,上面寫法也有些瑕疵,串列部分難道要寫成[1,2,3,4,5,…,100]嗎? 沒錯,當然不可以這樣寫,這樣寫就落入我講的沒有效率,所以有沒有什麼現有的函數可以直接得到連續整數的串列,答案是有的,這個函數叫做range(),以下我們先簡單說明range()的用法,再將上面的程式優化。
程式碼
#range()相關用法
print("0~10連續整數的串列:{}".format(list(range(11))))
print("1~10連續整數的串列:{}".format(list(range(1,11))))
print("1~10中間隔為2的整數串列:{}".format(list(range(1,11,2))))
print("-10~10連續整數的串列:{}".format(list(range(-10,11))))
print("10~1連續整數的串列:{}".format(list(range(10,0,-1))))
print("10~1中間隔為2的整數串列:{}".format(list(range(10,0,-2))))
Python畫面
學會了range()的用法,我們就可以將這個問題一般化,即1+2+3+…+n的值,我們現在就來將上面的程式進行小小修改,就可以解決任何n值的問題。
程式碼
#for迴圈操作(3)
n=int(input("請輸入n值,計算1~n的總和..."))
Sum=0
for i in range(1,n+1):
Sum=Sum+i
print("<<迴圈結束!>> 1~{}的總和為{}".format(n,Sum))
Python畫面
再給大家一個練習題,將上面的程式做一點小修改,計算n!(n階乘)的值,我將我的寫法寫在下面給讀者參考,大家可先思考看看如何修改。
程式碼
#for迴圈操作(4)
n=int(input("請輸入n值,計算n!的值..."))
prod=1
for i in range(1,n+1):
prod=prod*i
print("<<迴圈結束!>> {}!的值為{}".format(n,prod))
Python畫面
前面介紹for迴圈都是在操作數值的資料型態,我們將前面的一個文本分析的例子進行推廣,列出所有出現的單字,並計算出現次數,並用表格呈現,大家可以想想如何撰寫,我將我的寫法寫在下面給大家參考。
程式碼
#簡易文本分析(2)
artic='''Enjoy that uniquenesss1. You do
not have to pretend in order to seem more like someone else. You do not have to
lie to hide the parts of you that are not like what you see in anyone else.
You were meant to be different. Nowhere, in
all of history, will the same things be going on in anyone’s mind, soul and
spirit as are going on in yours right now.
'''
artic=artic.lower() #將所有單字都變為小寫
artic=artic.replace("\n",
"") #移除\n符號
artic=artic.replace(",",
"") #移除,符號
artic=artic.replace(".",
"") #移除.符號
vocabulary_list=artic.split(" ")
#將文章切割為單字串列
vocabulary_list_Nondup=[] #移除重複出現的單字
print("{:<12s}{:<4s}".format("單字","出現次數"))
for v in vocabulary_list:
if v not in vocabulary_list_Nondup:
vocabulary_list_Nondup.append(v)
print("{:<14s}{:<4d}".format(v,vocabulary_list.count(v)))
Python畫面
我們最後再給一個例子,這個例子會用大量的for跟if敘述,正好將前面學過的再複習一次。我們建立一個成績登入系統,可以自由設定要登入多少位學生的成績,登入完成後,自動計算等級與平均分數並印出報表。
程式碼
#成績登入系統
print("成績登入系統".center(30,"="))
N=int(input("請輸入學生人數:"))
print("="*30)
sd_name=[];math_score=[];english_score=[]
for i in range(N):
sd_name.append(input("請輸入第"+str(i+1)+"位學生姓名:"))
math_score.append(float(input("請輸入該生數學成績...")))
english_score.append(float(input("請輸入該生英文成績...")))
print("-"*20)
print("學童成績表".center(40,"="))
print("{:<8s}{:<8s}{:<8s}{:<8s}{:<8s}".format("學生姓名","數學成績","英文成績","總平均","等級"))
for i in range(len(sd_name)):
ave=(math_score[i]+english_score[i])/2
if ave>=90:
grade="A"
elif 80<=ave<90:
grade="B"
elif 70<=ave<80:
grade="C"
else:
grade="D"
print("{:<11s}{:<12.2f}{:<11.2f}{:<11.2f}{:<1s}".format(sd_name[i],math_score[i],
english_score[i],ave,grade))
Python畫面
5-6 for迴圈的進階操作
在for迴圈的進階操作中,我們將介紹巢狀for迴圈,也就是進入for迴圈的程式區塊後還有for迴圈需要執行,以下我們用兩個例子來介紹如何撰寫巢狀for迴圈,第一個範例是印出99乘法表,第二個範例是執行矩陣乘法。
程式碼
#印出九九乘法
print("九九乘法表".center(82,"="))
for i in range(1,10):
for j in range(1,10):
print("{:<1d}*{:<1d}={:<2d}".format(j,i,j*i),end="
| ")
print()
Python畫面
程式碼
#執行兩個3*3矩陣的乘法
matA=[]
for i in range(1,4):
matA_row=input("請輸入A矩陣第{}列:(數字請以,隔開)".format(i))
matA.append(list(map(int,matA_row.split(","))))
print("矩陣A:{}".format(matA))
print("-"*40)
matB=[]
for j in range(1,4):
matB_row=input("請輸入B矩陣第{}列:(數字請以,隔開)".format(j))
matB.append(list(map(int,matB_row.split(","))))
print("矩陣B:{}".format(matB))
AB=[]
for row in range(3):
rowlist=[]
for col in range(3):
prodsum=0
for x in range(3):
prodsum=prodsum+matA[row][x]*matB[x][col]
rowlist.append(prodsum)
AB.append(rowlist)
print("="*40)
print("A*B={}".format(AB))
Python畫面
在矩陣乘法的例子中,我們有用到一個map()函數,在這裡主要是把串列中的數值字串轉成數值資料型態,才能做後續的數字乘法。我們可以參考以下網站了解map()函數的用法(https://www.runoob.com/python/python-func-map.html)
5-7 break 與 continue的使用
有時候我們會想中斷迴圈或跳過就可使用break與continue的語法,break會直接結束迴圈的執行,continue則是會直接跳過寫在continue以下的程式碼,會直接回到迴圈最上層,取下一個串列值再繼續往下執行。以下我們分別個給一個範例進行說明。
程式碼
#質數判斷器
n=int(input("請輸入一個大於1的正整數..."))
for i in range(2,round(n**(1/2))+1):
if n%i==0:print("{}不是質數!".format(n));break
else:print("{}是質數!".format(n))
Python畫面
我們這邊的for迴圈之後加了一個else,當break發生for迴圈結束,不會執行else的部分,如果不使用else,直接寫print("{}是質數!".format(n)),當break發生for迴圈結束時,會一併執行print("{}是質數!".format(n)),會出現是質數又不是質數的窘境。
程式碼
#樓層命名-(不含4樓)
n=int(input("請輸入樓層數..."))
print("樓層名稱為:",end="")
for i in range(1,n+2):
if i==4:
continue
print(i,end=" ")
Python畫面
5-8 while 迴圈的操作
常用的迴圈有兩種,for迴圈與while迴圈,這兩者最大的差異是for迴圈的執行次數是已知的,while迴圈則是可以用於已知與未知的狀況下,原因是他在執行時是用條件是進行判斷,以下是while迴圈的結構:
while 條件式:
程式區塊
也就是說,滿足條件式,則進入程式區塊執行程式,如不滿足,則結束while迴圈。以下我們用幾個例子,說明一下while迴圈的操作。
程式碼
#while的操作(1)
s=0
while s<30:
num=int(input("請繼續輸入數字,直到總和大於等於30即結束..."))
s=s+num
print("所有的數字總和為:",s)
Python畫面
程式碼
#while的操作(2)
print("計算根號2的近似值".center(30,"="))
a=1;b=2
accuracy=b-a
while(accuracy>0.0001):
m=(a+b)/2
if(m**2>2):
b=m
else:
a=m
accuracy=b-a
print("根號二介在{:.5f}~{:.5f}".format(a,b))
Python畫面
程式碼
#while的操作(3)
sentence="an apple a day keeps the
doctor away"
print("原始句子:",sentence)
s_list=sentence.split()
word=input("請輸入你要查詢的單字(輸入-1即跳出查詢):")
while (word!="-1"):
if word in s_list:
print("文章中\"存在\"此單字...")
print("="*30)
else:
print("文章中\"不存在\"此單字...")
print("="*30)
word=input("請輸入你要查詢的單字(輸入-1即跳出查詢):")
print("結束查詢....")
Python畫面
在使用while迴圈時要特別注意條件式的寫法,如果條件式總是True,會形成無窮迴圈,程式會一直執行停不下來,宛如當機的狀態,此時可以按Ctrl + C中斷程式,檢查程式的問題點,修改後再重新執行一遍。
留言
張貼留言