---
# System prepended metadata

title: 字典與集合
tags: [人生苦短，我學Python]

---

# 字典與集合
###### tags: `人生苦短，我學Python`

## 字典特徵
:::info
字典和陣列類似，也是可變序列，但它是無序的，保存的內容是以「鍵:值」的形式存放的。
鍵是唯一的，但值可以有很多個。

:fire: 特徵如下
:heavy_check_mark: 透過鍵而不是透過所引來讀取
:heavy_check_mark: 無序
:heavy_check_mark: 可變，可任意嵌套
:heavy_check_mark: 鍵必須唯一
:heavy_check_mark: 鍵不可變
:::

## 字典的新增
* 定義字典時，每個元素都包含兩個部分--鍵、值，兩者使用「:」隔開，所有元素都放在一個大括號中

* 創建空字典
```python=
# 有兩種方法
name = {}
name = dict()
```
* 也可以使用zip()函數
```python=
# name = dict(zip(list1, list2))

name = ['rex', 'xia', 'zhan']
sign = ['up', 'down', '5566']
test = dict(zip(name, sign))
print(test)
# {'rex': 'up', 'xia': 'down', 'zhan': '5566'}
```
* 透過給定的鍵值創鍵字典
```python=
name = dict(id = "12345", email = "rex@gmail")
print(name)
# {'id': '12345', 'email': 'rex@gmail'}
```

* 也可以使用fromkeys()創建空字典
```python=
name = ['xia', 'rex']
test = dict.fromkeys(name)
print(test)
# {'xia': None, 'rex': None}
```


* 也可以使用已經存在的元組和陣列創建字典
```python=
# 元組:陣列、陣列:元組、元組:元組

name = ['xia', 'rex']
test = ('1', '2')
# (1)
dict1 = {test : name}
print(dict1)
# {('1', '2'): ['xia', 'rex']}

# (2)
dict2 = {name : test}
print(dict2)
# Traceback (most recent call last):
  #File "C:\Users\a9132\Desktop\python\1.py", line 3, in <module>
    #dict2 = {name : test}
#TypeError: unhashable type: 'list'

# (3)
dict3 = {test : test}
print(dict3)
# {('1', '2'): ('1', '2')}
```

## 刪除字典
```python=
dict_example = {'2':'3', '4','5'}
del dict_example

# 將字典內部清空
dict_example.clear()
```

:::warning
當然還有pop()、popitem()等方法。這邊可以自己試一下
:accept: dict.pop(keyword)
:accept: dict.popitem() 直接刪除末尾的key-value
:::

## 字典搜索

* 直接搜尋
```python=
name = {"1":"2", "3":"4"}
print(name["1"])
# 2
```

* 但實際在處理的時候，不一定會知道當前有什麼鍵......，比如可以這樣寫
```python=
name = {"1":"2", "3":"4"}
print(name["5"] if "5" in name else "查無此鍵")
# 查無此鍵
```

* 使用get()得到value
```python=
name = {"1" : "2", "3" : "4"}
get_value = name.get("1")
print(get_value)
# 2

none_keyword = name.get("5", "沒有此key值")
print(none_keyword)
# 沒有此key值
```
:::warning
在使用get()的時候，如果沒有找key，也就是key不存在的時候，得到的結果就是默認值
:::

## 遍歷字典
```python=
# 需要用dict.items()函式獲得字典的鍵值對列表

name = {"1" : "2", "3" : "4"}
for item in name.items():
    print(item)
# ('1', '2')
# ('3', '4')
```

* 如果想要獲取具體的每個鍵和值......
```python=
name = {"1" : "2", "3" : "4", "5" : "6"}
for key, value in name.items():
    print(key, " 的下一個是 ", value)
# 1  的下一個是  2
# 3  的下一個是  4
# 5  的下一個是  6
```
:::success
這邊也提供了values()、keys()，用於返回值、鍵

:key: keys()會返回 ["鍵值", "鍵", ......]
:tea: values()回返回 dict_values(["值", "值", ......])
:::

## 添加字典元素
* 因為字典是可變序列，所以可以隨時增加鍵-值對
```python=
name = {"1" : "2", "3" : "4", "5" : "6"}
name['7'] = '8'
print(name)
# {'1': '2', '3': '4', '5': '6', '7': '8'}
```

## 修改字典元素
```python=
name = {"1" : "2", "3" : "4", "5" : "6"}
name["1"] = '0'
print(name)
# {'1': '0', '3': '4', '5': '6'}
```
## 刪除字典元素
```python=
name = {"1" : "2", "3" : "4", "5" : "6"}
del name['1']
print(name)
# {'3': '4', '5': '6'}
```

## 字典生成式
* 可快速生成字典
```python=
import random

randdict = {i : random.randint(0, 100) for i in range(1, 5)}
print(randdict)
# {1: 35, 2: 88, 3: 38, 4: 77}
```

## 集合介紹
:::info
:+1: 集合分為兩種，可變集合、不可變集合，本文已可變集合為主，也就是set函數的應用
:::


## 創建集合
* 直接用 {} 創建
```python=
name = {1, 2, 3, 6, 5, 0}
print(name)
# {0, 1, 2, 3, 5, 6}
```
:::warning
set()是無序的，所以每次輸出的排序可能不同，不用在意
:::

* 使用set()函數建立
```python=
# setname = set(iteration)

name = set([1, 1, 2, 3, 4, 4])
print(name)
# {1, 2, 3, 4}
```
:::warning
當出現重複元素時，會刷掉
:::

## 往集合裡添加元素
* 使用add()函數
```python=
name = set([0, 1, 2, 3])
name.add(4)
print(name)
# {0, 1, 2, 3, 4}
```
## 在集合裡刪除元素
* 範例
```python=
name = set([0, 1, 2, 3, 4, 5])
name.remove(0)
print(name)
# {1, 2, 3, 4, 5}

name.pop()
print(name)
# {2, 3, 4, 5}

name.clear()
print(name)
# set()
```
## 使用交集、合集、差集運算
:::success
:cactus: 交集使用「&」
:cactus: 合集使用「|」
:cactus: 差集使用「-」
:cactus: 對稱差集使用「^」
:::

* 範例
```python=
name = set([0, 1, 2, 3])
example = set([0, 2, 3, 7])

print("交集: ", name & example)
# 交集:  {0, 2, 3}

print("合集: ", name | example)
# 合集:  {0, 1, 2, 3, 7}

print("差集: ", name - example)
# 差集:  {1}
```


{%hackmd S1DMFioCO %}