# Dictionary
周楷翔 @ 資芽 2022 北區 Py 班
參考自 2020 北區 by robert1003 & 2021 竹區 by Sylveon
~~(費波那契簡報)~~
---
## 複習一下 List
還記得那是什麼齁
----
```python=
primes = [2, 3, 5, 7, 10]
primes[4] = 11
print(primes[0])
```
----
如果我想登記大家的成績,就把學號當成 index
```python=
score = list()
score[10712345] = 87 # 該怎麼避免 IndexError?
```
(不要這麼做,拜託)
----
可是敝校的學號有英文字母...
```python=
score = list()
score["B07705022"] = 87
# TypeError: list indices must be integers or slices, not str
```
真的不行了...
除了轉學以外,有其他方法嗎?
----
這就是為什麼我們需要 Dictionary!
---
什麼是 Dictionary
----
- 回想一下你知道的「字典」的功能:
把每個「字」對應到「解釋」
- Python 的 dictionary 的功能:
把 "key" 對應到 "value"
----
- List 的功能之一是從「整數」作為 key,對應到數值
- 記得 List 本身有其他意義
- Dictionary 可以把「任意內容」作為 key,對應到數值
- 也不是任意啦... 等等會講
----
大括號代表 dict
```python=
score = {} # or score = dict()
```
預設內容用 `:` 區隔 key 與 value(i.e., `key: value`)
```python=
score = {"Alice": 36, "Bob": 37}
```
----
稍微複習一下
```python=
my_list = []
my_tuple = ()
my_dict = {}
```
---
## 取值
----
```python=
score = {"Alice": 36, "Bob": 37}
print(score["Alice"])
print(score["Bob"])
print(score["Carol"]) # 等等,這不存在啊?
```
```
36
37
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-1-34eaef53f35c> in <module>()
2 print(score["Alice"])
3 print(score["Bob"])
----> 4 print(score["Carol"])
KeyError: 'Carol'
```
----
有沒有方法避免噴出 KeyError 呢?
```python=
if "Carol" in score: # 不會進去這個 if
print(score["Carol"])
print(score.get("Carol")) # 回傳 None
print(score.get("Carol", 0)) # 回傳 0
```
`get(key, default value)`:
- 如果 key 存在,就回傳對應的 value
- 否則回傳 default value,如果沒有 default value 就回傳 None
---
## 新增、修改
----
新增:直接用 `=` 賦值即可
```python=
score["Carol"] = 100
print(score)
# {'Alice': 36, 'Bob': 37, 'Carol': 100}
```
----
修改:直接用 `=` 賦值即可
```python=
score["Alice"] = 80
print(score)
# {'Alice': 80, 'Bob': 37, 'Carol': 100}
```
恩對,兩個長得一模一樣
----
## Practice!
`observations` 裡面,每個字元分別出現幾次?
```python=
observations = ["a", "b", "c", "d", "a", "e", "c", "f", "f", "c"]
```
P.S. 輸出是
```
{'a': 2, 'b': 1, 'c': 3, 'd': 1, 'e': 1, 'f': 2}
```
----
## Practice!
[neoj 3055](https://neoj.sprout.tw/problem/3055)
---
## 遍歷
----
方法一:`for key in dict.keys`
```python=
for k in score.keys():
print(k)
```
遍歷的是 key
```
Alice
Bob
Carol
```
----
方法二:`for value in dict.values()`
```python=+
for v in score.values():
print(v)
```
遍歷的是 value
```
80
37
100
```
----
方法三:`for key, value in dict.items()`
```python=
for k, v in score.items():
print(k, v)
```
key 跟 value 同時遍歷,以 `(key, value)` 的 tuple 表示
```
Alice 80
Bob 37
Carol 100
```
----
## Practice!
[neoj 3052](https://neoj.sprout.tw/problem/3052)
---
## 刪除
----
方法一:`pop`
```python=
score.pop("Alice") # 可以注意一下這回傳什麼
print(score) # {'Bob': 37, 'Carol': 100}
```
刪除指定的 key(以及他對應到的 value)
----
方法二:`del`
```python=
del score["Bob"] # 注意一下,這有回傳值嗎?
print(score) # {'Carol': 100}
```
----
方法三:`clear`
放大絕,全部清空!
```python=
score.clear()
print(score) # {}
```
----
## Practice!
[neoj 3035](https://neoj.sprout.tw/problem/3035)
---
## 進階一點的東西
聽不懂就算了
----
並不是什麼東西都能當 key
```python=
score[[1, 2, 3]] = 456
```
```
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
```
原因有點複雜(關鍵字:immutable),總之拿 int, float, str, tuple 可以當 key 不會遇到這些問題
----
Dictionary 是沒有排序的
```python=
dict1 = {"Alice": 100, "Bob": 87}
dict2 = {"Bob": 87, "Alice": 100}
print(dict1) # {'Alice': 100, 'Bob': 87}
print(dict2) # {'Bob': 87, 'Alice': 100}
print(dict1 == dict2) # True
```
(從 Python 3.7 起,Dictionary 的順序保證會是插入順序)
----
Dictionary 有許多不同的名字:associative array, map, symbol table
不同語言可能會以不同的名字提供相同的功能
e.g. C++ 的 `<map>`
---
## 作業
[neoj 3054](https://neoj.sprout.tw/problem/3054)
[neoj 3036](https://neoj.sprout.tw/problem/3036)
Bonus: [neoj 3015](https://neoj.sprout.tw/problem/3015)
{"metaMigratedAt":"2023-06-16T21:17:32.827Z","metaMigratedFrom":"YAML","title":"Dictionary","breaks":true,"robots":"none","contributors":"[{\"id\":\"a30e4bd0-d7eb-41e2-898b-8571fad354d3\",\"add\":7406,\"del\":3441}]"}