###### tags: `Python` # List、Tuple 與 二維 List **<a href="https://hackmd.io/@Mes/python_note" class="redlink">點此回到 Python筆記 目錄</a>** # # 前言 在寫程式時可能會有一些資料可以把他們綁在一起,舉個例子,我們現在要把班上同學的名字全部列出來,那我們可以用很多的變數來存名字,並一個一個print出來,但這樣太麻煩了。為了應對這種狀況,我們可以把有相關性的資料利用「容器」把它們包裝在一起,那「容器」有很多種,你可以把他想成有很多種包裝的方法,那我們接下來會講最常見的 「List」 和 「Tuple」。 # List: ```python= classmate = ["Ina", "Ame", "Gura", "Kiara", "Calli"] print(classmate) print() print(classmate[0]) print(classmate[1]) print(classmate[2]) print(classmate[3]) print(classmate[4]) print() print(classmate[-5]) print(classmate[-4]) print(classmate[-3]) print(classmate[-2]) print(classmate[-1]) ``` 上面這個例子我們利用了 List 這種「容器」 把班上同學的名字全部存下來了,然後再利用 `print` 把它們印出來。那現在我們來看看語法吧!首先看第一行,我們要生成一個List時,前後需要用 `[]` 包住,而中括號內的就是 List 的內容,再用賦值運算符`=` 將這個 List 命名(儲存),以上例來講,`["Ina", "Ame", "Gura", "Kiara", "Calli"]` 這個 List 的內容就是五位同學的名字,然後 List 的名字叫做 classmate,往後要使用這個 List 的時候,就會利用 classmate 來呼叫它,像是第三行的 `print(classmate)` ,我們就會把名叫 「classmate」 的 List 給印出來。 接下來看下方的五個 `print` ,括號內我們傳入了 `classmate[數字]` ,這就是呼叫 List 元素的方法,前面會有我們要呼叫的 List 的名字,並在名自後方接上 `[]` , `[]`內要填入一個數字,那這個數字是什麼意思呢? 它代表了我們要呼叫的東西是在 List 內的第幾個,要注意的是我們是從 0 開始數的,因此 `["Ina", "Ame", "Gura", "Kiara", "Calli"]` 內的 `"Ina"` 就會是第 0 個,而 `"Ame"` 就會是第一個,以此類推。 那如果我們填入的是一個負數呢? 如果填入了負數,在這裡的意義會代表「從後面數來第幾個」,要注意的是與正數不同,從後面數來的話第一個數字會是「1」,也就是說 `"Calli"` 的編號會是 「-1」,而 `"Kiara"` 則是「-2」,以此類推。 另外,這個數字我們有給它一個名字,叫做 index(索引)。 那接下來我們來看看一些和 List 相關的函式和運算符吧! ```python= number = [0, 1, 2, 3, 4] # + 號 PlusCopy_number = number + number PlusList_number = [0, 1, 2, 3, 4] + [0, 1, 2, 3, 4] print("PlusCopy_number = ", PlusCopy_number) print("PlusList_number = ", PlusList_number) print() # * 號 MultiCopy_number = number*2 MultiList_number = [0, 1, 2, 3, 4]*2 print("MultiCopy_number = ", MultiCopy_number) print("MultiList_number = ", MultiList_number) print() # : 冒號 print("number[0:5:1] = ", number[0:5:1]) print("number[0:5] = ", number[0:5]) print("number[1:3:1] = ", number[1:3:1]) print("number[1:3:2] = ", number[1:3:2]) print("number[0: ] = ", number[0: ]) print("number[ :5] = ", number[ :5]) print("number[ : ] = ", number[ : ]) print("number[ : : ] = ", number[ : : ]) print("number[0:5:2] = ", number[0:5:2]) print("number[ : :2] = ", number[ : :2]) print() # len函式 number_lenth = len(number) print("number_lenth = ", number_lenth) print() # append 、 remove 與 clear number.append(5) print("number.append(5)後 = ", number) number.remove(5) print("number.remove(5)後 = ", number) number.clear() print("number.clear()後 = ", number) print() #------------初始化number------------- number = [0, 1, 2, 3, 4] print("重新宣告了number = ", number) print() #------------------------------------ # insert 與 pop number.insert(0,100) print("number.insert(0,100) = ", number) number.pop(0) print("number.pop(0)後 = ", number) ``` 首先我們看 + 號和 * 號,和字串一樣,我們可以利用 + 號來連接 List,用 * 號來將 List 延長。 再來看 : 冒號,第一行` print("number[0:5:1] = ", number[0:5:1])` 裡, `number[0:5:1]` 裡面有三個數字,由左至右代表的意思分別為 「從哪裡開始」、「到哪裡前結束」 與 「間格為多少」,與上次教到的 For 迴圈後面接的 `range()`很像。 最左邊的數字如果沒填,預設為0; 中間的數字如果沒填,預設為陣列的最後一個; 最後的數字如果沒填,預設為1。 如果間隔是 1 的話,我們可以把第二個冒號省略掉。 那現在看到函式的部分,常用的有這 5 個函式,這邊我列個表格把他們的功能寫出來: | 函式 | 意義 | | -------- | -------- | | append() | 新增括號內傳入的參數,會在 List 的最尾端 | | remove() | 移除List裡,括號內填入的參數,ex. remove(5) 就是把 5 這個元素給刪掉,如果沒這個元素會噴錯 | | clear() | 將 List 清空 | | insert() | 插入括號內傳入的參數,第一個參數代表要插入的index,第二個參數代表要插入的值 | | pop | 刪除 index 為括號內傳入的參數的元素,ex. pop(2)就是把第 3 個元素刪掉 | # List 與 For迴圈 的應用 還記得上次我們說 For迴圈的 `in` 後方要接一個「容器」或「範圍」嗎? 現在我們已經學會了 List,List是一種容器,那我們來看看兩者之間要怎麼搭配使用吧: ```python= classmate = ["Ina", "Ame", "Gura", "Kiara", "Calli"] for name in classmate: print(name) print() print(name) ``` 在上例中,我們在關鍵字 `in` 後方接了 `classmate` ,如此一來「變數name」就會遍歷 classmate 一次,而我們再把它print出來,因此這個程式就會把整個 classmate 給印出來。 另外還有一種用來創建 List 的特殊用法,是搭配 For迴圈 來運作的,假設我們要創建一個包含 0~4 這五個數字的 List,剛剛我們是直接 `number = [0, 1, 2, 3, 4]` 這樣創建,但還可以這樣做: ```python= number = [num for num in range(5)] print(number) ``` `for` 關鍵字的前方通常會加上與後方變數有關的變數,講起來很繞口,以上例來講,`for` 後面的變數是 `num`,它的值會從 0 開始跑到 4,而 `for` 前方的變數則代表每次迴圈執行,要加入迴圈的值是什麼,以上例來說就是 `num` ,也就是說上例第一行,在每次迴圈都會將`num` 加到 `number` 這個 List。 這是個好用的技巧,可以幫助我們快速的創建 List,在多看幾個例子: ```python= number = [num**2 for num in range(5)] print(number) number_two = ["hi" for _ in range(5)] print(number_two) ``` 第一行把 0~4 的平方加進了 number 這個 List,而第四行,每次執行迴圈都會把 「"hi"」 這個字串加進 number_two 這個 List,而迴圈會執行5次。 這邊有一個小習慣,那就是如果 `for` 後面接的變數我們不會用到的話,通常我們會使用 `_` 來代替它,以第二個例子來講,每次迴圈要做的事是「加一個"hi"到 List 內」,所以 `for` 後面的變數我們不會用到它,它只是一個計數器,因此我們會用 `_` 來寫。 # Tuple Tuple 與 List 很像,差別在於 Tuple 的元素不能被修改,也不能刪除和增加元素進去。 ```python= classmate = ("Ina", "Ame", "Gura", "Kiara", "Calli") print(classmate) print() print(classmate[0]) print(classmate[1]) print(classmate[2]) print(classmate[3]) print(classmate[4]) print() print(classmate[-5]) print(classmate[-4]) print(classmate[-3]) print(classmate[-2]) print(classmate[-1]) ``` Tuple 前後的符號為 `()` ,要小心別和 List 搞混了,那麼 Tuple 有什麼好處呢,有兩點? + 元素無法修改 你可能會想說奇怪,不能修改為什麼算是好處? 事實上很多時候資料是唯讀的,能減少被改動到的機會就盡量減少,這樣程式出錯的機率會比較低,如果你的資料是不需要改動的,那就盡量使用 Tuple 。 + 創建時間和占用的空間都優於 List # 二維 List List 內的元素也可以是容器,假設我們今天的 List 要印出全班同學的名字與成績,那我們可以怎麼做呢? 看看下面的例子: ```python= classmate = [ ["Ina",100], ["Ame",99], ["Gura",98], ["Kiara",97], ["Calli",96] ] print(classmate) print() for people in classmate: print(people) ``` 上例中的 `classmate` 內的每個元素都是一個 List ,這種 List 我們就稱它為 「二維List」,那它的複雜度就會比較高了,假設我們現在想替每個同學加上號碼,可以怎麼做呢? ```python= classmate = [ ["Ina",100], ["Ame",99], ["Gura",98], ["Kiara",97], ["Calli",96] ] for number in range(0, len(classmate)): classmate[number].insert(0, f"{number+1} 號") print(classmate) print() for people in classmate: for element in people: print(element, end = " ") print() ``` 我們看到第四行的 `classmate[number].insert(0, f"{number+1} 號")`,首先, `classmate[number]` 代表了 `classmate` 內的第幾個元素,我們現在假設 number 是 0 ,因次第四行就會是 `classmate[0].insert(0, f"{0+1} 號")` , `classmate[0]` 代表第一個元素,也就是 `["Ina",100]` ,而這也是一個 List ,因此我們可以對它使用跟 List 有關的函式,像是上例的 `insert` ,如果有點搞混,可以這樣想像, `classmate[0]` 就是 `["Ina",100]` ,所以 `classmate[0].insert(0, f"{0+1} 號")` 可以替換成 `["Ina",100].insert(0, f"{0+1} 號"` ,實際上並不是這樣,但這樣想像也許會比較好懂。 而下方印出 classmate 的 For迴圈 有兩層,我們先看外面這層 `for people in classmate:` ,「變數people」會遍歷 `classmate`,因此 `people` 也會是一個 List ,迴圈第一次執行時 `people` 會是 `['1 號', 'Ina', 100]` ,第二次會是 `['2 號', 'Ame', 99]` ,以此類推。 再來我們看到內層的迴圈 `for element in people:` ,「變數element」 會遍歷 `people` ,要記住 `people` 是一個 List ,因此 `element` 會是 `people` 的元素,之後我們在把 `element` 給print出來,如此一來就會把整個 classmate 給印出來了。 那我們可以利用上面學到的 List 與 For迴圈 搭配應用的創建方法來做出一個二維 List: ```python= number = [ [num for num in range(5)] for _ in range(5)] for i in number: for j in i: print(j,end = " ") print() ``` 另外,除了遍歷的方式,我們也可以利用計數器這樣印出 number: ```python= for i in range(len(number)): for j in range(len(number[i])): print(number[i][j], end = " ") print() ``` # 練習 ### 練習1:利用 List 來完成輸入與輸出 > 輸入數字,並利用 List 儲存我們的輸入,當輸入 -1 時將剛剛的輸入全部印出來並結束程式 > 提示:利用迴圈來完成重複,並利用 `append()` 來新增元素進 List 參考解答: ```python= L = [] while (True): n = int(input("> ")) if (n == -1): for x in L : print(x, end = " ") break L.append(n) ``` ### 練習2:利用 二維List 來印出數字塔 > 輸入一個層數,並且蓋出相對層數的數字塔, ex: ```python= 輸入:6 輸出: 1 2 2 3 3 4 4 5 5 66666666666 ``` > 提示:想想看數字塔每個「有數字的位置」和「輸入的數字」的規則是什麼 > > 註:這題比較難寫,因為要求了要用 二維List 給大家練習,如果想不出來可以先直接用 For迴圈 印出來後再來想看看 參考解答: ```python= n = int(input("> ")) L = [ [" " for _ in range(2*n-1)] for _ in range(n) ] L[0][n-1] = 1 for i in range(1,n-1): L[i][n-1-i] = i + 1 L[i][n-1+i] = i + 1 L[n-1] = [ n for _ in range(2*n-1)] for x in L: for y in x: print(y ,end="") print() ``` # 額外文章 其實 String 也是一種 List,因此對 List 的操作也可以套用到 String 上,有興趣的可以去看看文章: **<a href = "https://nbis.pixnet.net/blog/post/58243647" class = "redlink">[python] 字元、字串(string)與串列(list)的差別</a>** <br> 另外還有一些別的容器,但我這次只講了 List 和 Tuple,有興趣的可以看看課本: **<a href="https://github.com/jackfrued/Python-100-Days/blob/master/Day01-15/07.%E5%AD%97%E7%AC%A6%E4%B8%B2%E5%92%8C%E5%B8%B8%E7%94%A8%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84.md" class = "redlink">07.字符串和常用數據結構</a>** <style> .green { color:#29E5A9; } .brown { color:#990000; } .pink { color:#C18387; } .red { color:#E71B18 ; } .blue { color:#0b5394; } .purple { color:#AC9FDD; } @-webkit-keyframes A { 0% { color:#C10066;} 10% { color: #CC0000;} 20% { color: #E63F00; } 30% { color:#EE7700; } 40% { color: #DDAA00; } 50% { color:#EEEE00;} 60% { color: #99DD00;} 70% { color:#66DD00;} 80% { color: #00DDDD;} 90% { color: #0044BB;} 100% { color: #A500CC;} } #animation_title{ animation: A 3s ease 0s infinite alternate; -webkit-animation: A 3s ease 0s infinite alternate; } </style> <style> a.redlink { color:#DF2F6A; } a.redlink:link { color:#DF2F6A; text-decoration:none; } a.redlink:visiteid { color:#DF2F6A; text-decoration:none; } a.redlink:hover { color:#19CABC; text-decoration:none; } a.redlink:active { color:#000000; text-decoration:underline; background:#FFFFFF; } </style> <style type="text/css"> h1 { font-size:; color:#0b5394; } h2 { font-size:; color:#0b5394; } p { font-size:; color:; } h3 { font-size: ; color:#990000; } h4 { font-size:; color:#990000; } </style>