###### 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>