---
title: Python 入門教學-資料結構
tags: python_beginner
---
# 資料結構
## 串列
* 特性
* mutable
* 可在任何位置新增與刪除
* 可放置各種元素
```python=
>>> a = ['hello', 1, 3.14]
```
* 建立串列
```python=
>>> empty_list = []
>>> another_empty_list = list()
```
* 將其他資料類型轉換為串列
```python=
>>> list('cat')
['c', 'a', 't']
```
* 用Index取得與更改項目
```python=
>>> a = [1, 2, 3]
>>> a[1]
2
>>> a[1] = 10
>>> a
[1, 10, 3]
```
* 用Slice取得項目
```python=
>>> students = ['Sam', 'Jerry', 'Vincent']
>>> students[0:2]
['Sam', 'Jerry']
```
* 串列中的串列
```python=
>>> classA = ['Sam', 'Jerry', 'Vincent']
>>> classB = ['Tom', 'Paul', 'David']
>>> classC = ['John', 'Ray']
>>> classes = [classA, classB, classC]
>>> classes
[['Sam', 'Jerry', 'Vincent'], ['Tom', 'Paul', 'David'], ['John', 'Ray']]
```
* append(): 將項目新增到結尾
```python=
>>> classA = ['Sam', 'Jerry', 'Vincent']
>>> classA.append('Anna')
>>> classA
['Sam', 'Jerry', 'Vincent', 'Anna']
```
* in: 檢查串列中是否存在某個值
```python=
>>> 'Sam' in classA
True
>>> 'John' in classA
False
```
* sorted(): 回傳排序後的複本
```python=
>>> classA_sorted = sorted(classA)
>>> classA_sorted
['Anna', 'Jerry', 'Sam', 'Vincent']
```
* sort(): 直接排序項目
```python=
>>> classA.sort()
>>> classA
['Anna', 'Jerry', 'Sam', 'Vincent']
```
* len(): 取得串列長度
```python=
>>> len(classA)
4
```
* 複製
* 複製串列的時候不能直接用等於
```python=
>>> classA_copy = classA
>>> classA_copy
['Anna', 'Jerry', 'Sam', 'Vincent']
>>> classA[0] = 'Adele'
>>> classA
['Adele', 'Jerry', 'Sam', 'Vincent']
>>> classA_copy
['Adele', 'Jerry', 'Sam', 'Vincent']
```
* copy()
```python=
>>> classA_copy2 = classA.copy()
>>> classA[0] = 'Anna'
>>> classA
['Anna', 'Jerry', 'Sam', 'Vincent']
>>> classA_copy2
['Adele', 'Jerry', 'Sam', 'Vincent']
```
* del: 用index刪除項目
```python=
>>> del classA[0]
>>> classA
['Jerry', 'Sam', 'Vincent']
```
* remove(): 用值刪除項目
```python=
>>> classA.remove('Jerry')
>>> classA
['Sam', 'Vincent']
```
* pop(): 取得並刪除項目
* pop() 結尾
```python=
>>> classA.append('Brandon')
>>> classA.append('Bryan')
>>> classA.append('Allen')
>>> classA
['Sam', 'Vincent', 'Brandon', 'Bryan', 'Allen']
>>> classA.pop()
'Allen'
>>> classA
['Sam', 'Vincent', 'Brandon', 'Bryan']
```
* pop(0) 開頭
```python=
>>> classA.pop(0)
'Sam'
>>> classA
['Vincent', 'Brandon', 'Bryan']
```
* pop(x) 其他地方
```python=
>>> classA.pop(1)
'Brandon'
>>> classA
['Vincent', 'Bryan']
```
* insert(): 插入項目
```python=
>>> classA.insert(1, 'Brandon')
>>> classA
['Vincent', 'Brandon', 'Bryan']
```
* extend(), += : 結合串列
* index(): 尋找某個值的index
* count(): 計算某個值出現次數
* join(): 串列轉換成字串
## Tuple
* 建立空的Tuple
```python=
>>> empty_tuple = ()
```
* 建立一個元素的Tuple
```python=
>>> class_tuple = 'Sam',
>>> class_tuple
('Sam',)
```
> 有沒有括號沒有差別,重點在逗點
* 建立多個元素的Tuple
```python=
>>> class_tuple2 = 'Sam', 'John', 'Brandon'
>>> class_tuple2
('Sam', 'John', 'Brandon')
```
* Tuple unpacking: 將Tuple指派給多個變數
```python=
>>> p1, p2, p3 = class_tupl2
>>> p1
'Sam'
>>> p2
'John'
>>> p3
'Brandon'
```
* Tuple vs. List
* Tuple是immutable
* Tuple佔用空間較少
* 不會不小心破壞Tuple的資料
* Tuple可以當作dictionary的key
## 字典
* 特性
* Key / Value
* Key不可重複
* 沒有順序(3.6版以後會保持順序了)
* mutable
* 建立字典
```python=
>>> empty_dict = {}
>>>
>>> empty_dict2 = {'Name1':'Sam', 'Name2':'Jack'}
>>>
>>> classA = ['Sam', 'John', 'Paul']
>>> classB = ['Vincent', 'Sean']
>>> classC = ['Jobs', 'Tim', 'Tom']
>>> classes = {'classA': classA,
... 'classB': classB,
... 'classC': classC}
```
* 串列 or Tuple轉換成字典
```python=
>>> year = [['Sam', 21], ['John', 20], ['Paul', 19]]
>>> nickname = (('Sam', 'Potato'), ('John', 'Apple'), ('Paul', 'Lemon'))
>>> year_dict = dict(year)
>>> nickname_dict = dict(nickname)
```
* 用[key]添加或變更元素
```python=
>>> year_dict['Sam'] = 22
>>> year_dict['John'] = 21
>>> year_dict['Paul'] = 20
>>> year_dict['Jack'] = 23
>>> year_dict['Sam'] = 25
```
* update(): 合併字典
```python=
>>> new = {
... 'Jerry': 20,
... 'Jobs': 22,
... 'Loranz': 21
... }
>>> year_dict.update(new)
>>> year_dict
```
* del: 刪除項目
```python=
>>> del year_dict['Loranz']
>>> year_dict
```
* clear(): 刪除所有項目
```python=
>>> year_dict.clear()
>>> year_dict
```
* in: 測試有沒有這個key
```python=
>>> 'Sam' in year_dict
>>> 'Loranz' in year_dict
```
* 用[key]取得元素
```python=
>>> year_dict['Sam']
>>> year_dict['Loranz']
```
* 先用in測試
```python=
>>> 'Jobs' in year_dict
>>> year_dict['Jobs']
```
* 用get()函式
```python=
>>> year_dict.get('Jobs')
>>> year_dict.get('Job', 'Not in the class')
```
* keys(): 取得所有key
```python=
>>> year_dict.keys()
>>> year_dict_keys = list(year_dict.keys())
```
* values(): 取得所有value
```python=
>>> list(year_dict.values())
```
* items(): 取得所有key/value
每個key/value會以Tuple回傳
```python=
>>> list(year_dict.items())
```
* 複製
* 不要用 =
```python=
>>> year_dict_copy = year_dict
>>> year_dict['Jobs'] = 33
>>> year_dict_copy
```
* copy()
```python=
>>> year_dict_copy2 = year_dict.copy()
>>> year_dict['Jobs'] = 50
>>> year_dict_coty2
```
## 集合
* 特性
* 唯一值
* 布林運算
* 沒有順序
* mutable
* 建立集合
```python=
>>> empty_set = set()
>>> even_numbers = {0, 2, 4, 6, 8}
>>> odd_numbers = {1, 3, 5, 7, 9}
```
> `empty_set = {}` 不會新增一個set,而是一個字典
* 用set()轉換其他資料類型
```python=
>>> set('letters')
>>> set(['Sam', 'John', 'Jobs'])
>>> set(('Sean', 'Jerry', 'Allen'))
>>> set(year_dict)
```
* add(): 新增元素
```python=
>>> even_numbers.add(10)
```
* remove(): 刪除元素
```python=
>>> even_numbers.remove(10)
```
* in: 測試有沒有這個值
```python=
>>> 2 in even_numbers
>>> 1 in even_numbers
```
* 布林運算
* 交集: &, intersection()
```python=
>>> a = {1, 2, 3, 4, 5}
>>> b = {4, 5, 6, 7, 8}
>>> a & b
>>> a.intersection(b)
```
* 聯集: |, union()
```python=
>>> a | b
>>> a.union(b)
```
* 差集: -, difference()
```python=
>>> a - b
>>> a.difference(b)
```
* 互斥或: ^, symmetric_difference()
```python=
>>> a ^ b
>>> a.symmetric_difference(b)
```
* 子集合: <=, issubset()
```python=
>>> a <= b
>>> c = {1, 2, 3}
>>> d = {1, 2, 3, 4, 5}
```
* 真子集合: <
不包含自己
```python=
>>> c < d
>>> c < c
```
* 超集合: >=, issuperset()
```python=
>>> d >= c
>>> d.issuperset(c)
>>> d >= d
````
* 真超集合: >
```python=
>>> d > c
>>> d > d
```
## 其他
python有一個module叫做collections,裡面有提供一些實用的資料結構,例如:
### defaultdict
原本的dictionary在某個情況上會出現小問題,用起來不是很方便,像是如果你要統計某人的出席次數
```python=
attend = ['sam', 'john', 'josh', 'sam', 'jack', 'john', 'josh', 'david', 'jack']
times = {}
for person in attend:
times[person] += 1
```
上面這種寫法會出錯,因為key不在字典裡的時候你就讓他加一,改成下面這種才不會錯
```python=
attend = ['sam', 'john', 'josh', 'sam', 'jack', 'john', 'josh', 'david', 'jack']
times = {}
for person in attend:
if person not in times:
times[person] = 0
times[person] += 1
else:
times[person] += 1
```
如果key不在的話,就先讓他初始化
這寫法可以用,但是有點麻煩,所以我們可以使用defaultdict,這個資料型態會在key不存在時自動新增初始值,可以這樣寫
```python=
from collections import defaultdict
attend = ['sam', 'john', 'josh', 'sam', 'jack', 'john', 'josh', 'david', 'jack']
times = defaultdict(int)
for person in attend:
times[person] += 1
```
## 作業
建立一個串列,裡面包含'tim berners-lee', 'linus torvalds', 'guido van rossum', 'alan turing'這四個人名
* 利用str函式將這些人名一個一個轉為大寫開頭(e.g. tim berners-lee -> Tim Berners-Lee)
* 去查查這幾個人在計算機科學當中分別貢獻了什麼重要的東西
* 把一個你覺得比較不喜歡的人從串列中刪掉,並且自己查一個在計算機科學當中你喜歡的名人,把他加入串列
* 建立一個字典,將這些人名作為key,把串列裡面的人貢獻的東西作為value