# List
2023 資訊之芽北區 Py 班
感謝去年講師濬哲讓我~~抄襲~~修改他的簡報
---
## 來記一些資訊好了
----
```python=
student1 = 100
```
<span>沒什麼問題,那就加一個<!-- .element: class="fragment" data-fragment-index="1" --></span>
----
```python=
student1 = 100
student2 = 87
```
<span>輕鬆簡單,那就再加幾個<!-- .element: class="fragment" data-fragment-index="1" --></span>
----
```python=
student1 = 100
student2 = 87
student3 = 77
student4 = 69
```
<span>如果有 10 個? 20 個? 100 個?<!-- .element: class="fragment" data-fragment-index="1" --></span>
---
## List
----
- 可迭代(iterable)
- 迭:輪流、更替,如:「更迭」。
- 《詩經.邶風.柏風》:「日居月諸,胡迭而微。」
- 可以重複
- 換言之,有不能重複的資料結構 e.g. set
- 有序
- 換言之,有無序的資料結構 e.g. set
<span>蛤?什麼是資料結構?<!-- .element: class="fragment" data-fragment-index="1" --></span>
----
用法
```python=
list1 = [] # 一個空的 list
list2 = list() # 另一個空的 list
list = [] # 不要這樣!為什麼?
```
----
基本上要塞什麼都可以
```python=
list1 = [905, "NGGYU", False, [1987, 7, 27], {3.14}, 905]
list2 = [list1] # 這會是什麼?
```
----
Length
```python=
list1 = []
print(len(list1)) #0
list1 = [1, 2, 3]
print(len(list1)) #3
```
----
猜猜看這會印出什麼
```python=
list1 = [1, 2, 3, [1, 2, 3], []]
print(len(list1))
```
----
list 裡面的東西要怎麼讀出來?
```python=
list1 = ["a", "b", "c", "d"]
print(list1[0]) # a
print(list1[3]) # d
print(list1[-1]) # d
```
----
(補充)等等,為什麼第一項是 `0`?
`[n]` 裡面的數字是「位移量」,不是「第幾個」
`[0]` 是指「從 list 開頭位移 0 個位置」,所以是第一個值
----
也可以一次取好幾個
`list[start:end:step]`
首項(含)、尾項(不含)、公差(預設為 1)
```python=
list1 = ["a", "b", "c", "d", "e", "f", "g"]
print(list1[1:3]) # ["b", "c"]
print(list1[0:-1]) # ["a", "b", "c", "d", "e", "f"]
print(list1[0:5:2]) # ["a", "c", "e"]
```
這稱為 Slicing
----
:chestnut::`grades` 裡面有全班的成績,請把前三個人的成績印出來,也把第偶數個人的成績印出來
```python=
grades = [100, 87, 78, 99, 47, 59, 39.49]
```
----
:rice: 解
```python=
grades = [100, 87, 78, 99, 47, 59, 39.49]
print(grades[:3])
print(grades[1::2])
```
----
如何修改特定數值
```python=
list1 = ["a", "b", "c", "d", "e"]
list1[1] = "p" # ["a", "p", "c", "d", "e"]
list1[2:4] = ["p", "l"] # ["a", "p", "p", "l", "e"]
```
----
list 的加法與乘法
```python=
list1 = [1, 2, 3]
print(list1 + [4]) # [1, 2, 3, 4]
print(list1 * 3) # [1, 2, 3, 1, 2, 3, 1, 2, 3]
print(list1) # list1 沒有被改,所以是 [1, 2, 3]
```
```python=
list2 = [1, 2, 3]
list2 += [4]
print(list2) # [1, 2, 3, 4]
list2 *= 3
print(list2) # [1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]
```
----
如何知道一個值有沒有在 list 中出現?
```python=
list1 = [1, 2, 3]
print(1 in list1) # True
print(10 in list1) # False
```
---
## list 的 method
先不要管 method 是什麼,總之就是黑魔法
----
`append`:加一項在最後面
```python=
list1 = [1, 2, 3]
list1.append(10) # [1, 2, 3, 10]
```
----
`extend`:加一群在最後面
```python=
list1 = [1, 2, 3]
list1.extend([4, 5, 6]) # [1, 2, 3, 4, 5, 6]
```
----
四者差在哪裡?
```python=
list1 = [1, 2, 3]
list1p = list1 + [4, 5, 6]
```
```python=
list2 = [1, 2, 3]
list2 += [4, 5, 6]
```
```python=
list3 = [1, 2, 3]
list3.append([4, 5, 6])
```
```python=
list4 = [1, 2, 3]
list4.extend([4, 5, 6])
```
----
四者差在哪裡?
```python=
list1 = [1, 2, 3]
list1p = list1 + [4, 5, 6]
# list1: [1, 2, 3]
# list1p: [1, 2, 3, 4, 5, 6]
```
```python=
list2 = [1, 2, 3]
list2 += [4, 5, 6] # [1, 2, 3, 4, 5, 6]
```
```python=
list3 = [1, 2, 3]
list3.append([4, 5, 6]) # [1, 2, 3, [4, 5, 6]]
```
```python=
list4 = [1, 2, 3]
list4.extend([4, 5, 6]) # [1, 2, 3, 4, 5, 6]
```
----
`insert(index, object)`:在指定位置插入一項
```python=
list1 = [1, 2, 3, 4]
list1.insert(3, 7) # [1, 2, 3, 7, 4]
list1.insert(100, 9) # [1, 2, 3, 7, 4, 9]
```
----
`pop()`:回傳最後一項並將其刪掉
```python=
list1 = [1, 2, 3, 4]
print(list1.pop()) # 4
list2 = []
print(list2.pop()) # IndexError
```

([source](https://dictionary.cambridge.org/zht/%E8%A9%9E%E5%85%B8/%E8%8B%B1%E8%AA%9E-%E6%BC%A2%E8%AA%9E-%E7%B9%81%E9%AB%94/pop))
----
`pop(index)`:回傳第 index 個值並將其刪掉
```python=
list1 = ['a', 'b', 'c', 'd']
print(list1.pop(2)) # 'c'
print(list1.pop(10)) # IndexError
```
----
`remove(obj)`:刪掉第一項值為 `obj` 的項
```python=
list1 = ['a', 'b', 'c', 'd', 'a', 'a']
list1.remove('a') # ['b', 'c', 'd', 'a', 'a']
list1.remove('z') # ValueError
```
----
`clear()`:全部清空
```python=
list1 = [1, 2, 3]
list1.clear() # []
```
----
`count(obj)`:值為 `obj` 的項出現幾次
```python=
list1 = [1, 1, 2, 3, 5, 8]
print(list1.count(1)) # 2
print(list1.count(47)) # 0
```
----
`index(obj)`
`index(obj, start)`
`index(obj, start, end)`
回傳從 `start` 到 `end` 出現的第一個 `obj` 的 index
```python=
list1 = [1, 2, 3, 1, 1, 2, 'no']
print(list1.index(1)) # 0
print(list1.index(1, 2)) # 3
print(list1.index(1, 4, 6)) # 4
print(list1.index("yes")) # ValueError
```
----
`sort()`, `reverse()`
顧名思義就是排序跟反轉
```python=
list1 = [1, 9, 2, 8, 3, 7, 4, 6, 5]
list1.sort() # [1, 2, 3, 4, 5, 6, 7, 8, 9]
list1.reverse() # [9, 8, 7, 6, 5, 4, 3, 2, 1]
list2 = list1[::-1] # 另一種 reverse 的方法,為什麼?
```
----
如何複製 list
```python=
a = [1, 2, 3, 4]
b = a
a[0] = 5
print(a)
print(b)
```
----
如何複製 list:`b = a.copy()`, `c = a[:]`
```python=
list1 = [1, 2, 3, 4]
list2 = list1
list3 = list1.copy()
list4 = list1[:]
list1[0] = 5 # [5, 2, 3, 4]
print(list2) # [5, 2, 3, 4]
print(list3) # [1, 2, 3, 4]
print(list4) # [1, 2, 3, 4]
```
---
## list 有關的 function
先不要管 function 是什麼,總之就是黑魔法
----
`list(iterable)`:把任何 iterable (例如 `range`)轉成 list
```python=
print(list(range(5))) # [0, 1, 2, 3, 4]
```
----
`max(list1)`, `min(list1)`, `sum(list1)`
```python=
list1 = [1, 2, 3]
print(max(list1)) # 3
print(min(list1)) # 1
print(sum(list1)) # 6
```
如果不使用內建 function,你會怎麼寫這些功能?
----
`sorted(l)`:回傳一個排好的 list
和 `l.sort()` 差在哪?
```python=
list1 = [1, 9, 2, 8, 3, 7, 4, 6, 5]
list2 = sorted(list1)
print(list1) # [1, 9, 2, 8, 3, 7, 4, 6, 5]
print(list2) # [1, 2, 3, 4, 5, 6, 7, 8, 9]
list3 = list1.sort()
print(list1) # [1, 2, 3, 4, 5, 6, 7, 8, 9]
print(list3) # None
```
<!-- ----
`map(func, iterable)`:對於每一項 `l[i]`,算出 `func(l[i])`
```python=
char_list = ['1', '2', '3', '4']
print(map(int, char_list)) # <map object at ......>
print(list(map(int, char_list))) # [1, 2, 3, 4]
# [int('1'), int('2'), int('3'), int('4')] = [1, 2, 3, 4]
```
-->
---
## for 迴圈
----
```python=
list1 = [1, 2, 3, 4, 6, 7, 8, 9]
for i in list1:
print(i)
```
----
```python=
list1 = [1, 2, 3, 4, 6, 7, 8, 9]
for i in range(len(list1)):
print(i, ls[i])
```
----
```python=
list1 = [1, 2, 3, 4, 6, 7, 8, 9]
for i, v in enumerate(list1):
print(i, v)
```
----
:chestnut::`grades` 裡面有全班的成績,請把 `grades` 裡面所有人的成績改成平方後除以 100
```python=
grades = [100, 87, 78, 99, 47, 59, 39.49]
```
----
:rice: 解
```python=
for i, j in enumerate(grades):
grades[i] = j**2 / 100
```
```python=
for i in range(len(grades)):
grades[i] = grades[i]**2 / 100
```
----
常見錯誤
```python=
for i in grades:
i = i**2/100
```
----
補充:關於變數命名
- 當使用 list 裡面的內容命名時,記得要複數
- 存放成績的 list 應該名為 `grades` 而非 `grade`
- 或是直接在變數名稱上註明這是一個 list
- `grade_list`
當程式碼越來越長時,良好的命名習慣可以避免看不懂自己在寫什麼
---
## 練習題
[Sprout OJ 327](https://neoj.sprout.tw/problem/327/)
[Sprout OJ 3032](https://neoj.sprout.tw/problem/3032/)
---
補充:List Comprehension
----
```python=
[x for x in range(10)] # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[x ** 2 for x in range(10)] # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
```
---
總結一下,所以何時該用 list?
- 有一些資料要儲存
- 不一定知道資料有多少個
- 資料可能增加、刪除、修改
- 這些資料可能有順序之分
- `[1, 2] != [2, 1]`
---
## 作業
[Sprout OJ 2005](https://neoj.sprout.tw/problem/2005/)
{"metaMigratedAt":"2023-06-17T23:16:10.546Z","metaMigratedFrom":"YAML","title":"List","breaks":true,"contributors":"[{\"id\":\"a30e4bd0-d7eb-41e2-898b-8571fad354d3\",\"add\":9123,\"del\":1777}]"}