# 03/18 python教學 *list/tuple/dict*
### list 列表
list 是 python 中最為基礎的一種資料結構,==有點類似小時候 c++ 學過的 array== (但是又多了{~~少部分~~|非常多}功能)
<i class="fa fa-pencil fa-fw"></i> **list 的基本宣告**
```python=
empty_list=[] #空list
integer_list = [1,2,3] #元素同型的list
heterogeneous_list =["penguin",0.1,True] #各種類型都有的list
list_of_list =[interger_list,heterogeneous_list,[]] #list裡面也可以放list喔~
```
---
### index (索引)是啥?
讓我們用下面的圖片簡單開始:
跟以前學的陣列一樣, index 的編號是由0開始的 **BUT!**
**Python 允許index為負數** 跟圖片上一樣,最後一個元素的索引值是 **-1**, 倒數第二個索引值為 **-2**, 以此類推~
---
### slice 切片
我們可以利用 slice 的功能,從 list 之中擷取一些我們需要的片段。
` [i:j] `這個片段表示從 **i** 到 **j-1** 的所有元素
誒...那個如果沒有設定開頭i怎麼辦:cold_sweat:
不用緊張~那當然就直接從頭開始取出片段嘍~ :smiley:
順帶一提,我們也可以用設定第三個參數 **k** 來指定間隔` [i:j:k] ` 表示從 **i** 開始每隔 **k** 取出一個元素
<i class="fa fa-pencil fa-fw"></i> **再來一段小練習**
```python=
x=[0,1,2,3,4,5,6,7,8,9]
a=x[-2]
last_three=x[-3:]
without_firstNlast=x[1:-1]
copy=x[:]
every_secon=x[::2]
guessWhat=x[5:2:-1]
```

<i class="fa fa-pencil fa-fw"></i> **~~跟上面無關但是你們之後解題會用到~~**
> 利用這種方式可以將list裡面的元素全部轉為整數型態
```python=
for i in range(len(List)):
List[i] = int(List[i])
```
>當然還有更酷的,我們可以利用==map==來轉換list內部元素的型態~
```python=
results = ['1','2','3','4']
print(results)
results = list(map(int,results))
print(results)
```
比較一下結果:

:::warning
暖身題 **(slice)**:zap:
請問如何利用slice將list進行reversal呢?
~~敢給我用reverse()給我試試看^^~~
* **【樣例輸入】**
1 2 3 4 5 6 7
* **【樣例輸出】**
[7, 6, 5, 4, 3, 2, 1]
:::
---
### 檢查元素是否在list裡面:
要怎麼知道list裡面有沒有-1這個元素?
python 裡面的`in`可以滿足你的願望~
`print(-1 in [1,2,3])`

同時,它也可以用來走訪整個列表~
<i class="fa fa-pencil fa-fw"></i> **利用關鍵字item的走訪**
```python=
characters=["五條悟","虎杖悠仁","伏黑惠","釘崎野薔薇"]
for item in characters: #直接輸出item
print(item)
```


:::warning
小練習1 (list):zap:
**a065 Jumping Mario**
:warning: 請用list來實現,output可能有點小問題要注意
:::
---
### ==**list 的基本運算以及常用函式**==
* **python 基本運算**
在 python 裡面, list只要**型態保持一致**,是可以直接用來進行運算的
<i class="fa fa-pencil fa-fw"></i> **基本運算範例(1)**
```python=
sentence=["重要的事情說三遍"]
x=[1,2,3,'哈摟']
print(sentence*3)
print(x+[5,6])
print(x+sentence)
print(sentence+3)
```


<i class="fa fa-pencil fa-fw"></i> **基本運算範例(2)**
```python=
sentence2=["他",4,"在幹嘛"]
x2=[1,2,3,'哈摟']
sentence2[2]=x2[2]+84
print(sentence2)
```

### **一些好用的python內部函式**
* `len()`: 可以用來看list的長度
* `str()`: 將list轉為字串
* `sum()`: 計算內部元素和
* `sorted()`: 會回傳排序好的list,但不會動到原本list
* `sort()`: 會直接對內部元素進行排序

* `reversed()`: 反轉list
### **更多好用的函式**
`listname.append(element)`:用於在list尾巴追加==元素==
`listname.extend(seq)`:直接在list尾巴加入另一個list(==另一組數字==)
`listname.count(obj)`: 計算某元素的出現次數
<i class="fa fa-pencil fa-fw"></i> **函式範例**
```python=
penguin_types1=["皇帝企鵝","國王企鵝","跳岩企鵝","阿德利企鵝"]
penguin_types2=["皇帝企鵝","小藍企鵝","麥哲倫企鵝"]
penguin_types1.append("皇帝企鵝")
print(penguin_types1)
penguin_types1.extend(penguin_types2)
print("length of penguin_types1=",len(penguin_types1))
print('penguin_types1=',penguin_types1)
print('皇帝企鵝次數:',penguin_types1.count('皇帝企鵝'))
```




| 皇帝企鵝 | 國王企鵝 | 跳岩企鵝 | 阿德利企鵝|
| -------- | -------- | --- | -------- |
|  |  | | |
---
### 二(多)維列表
**就是大家以前學的二(多)維陣列不解釋**
<i class="fa fa-pencil fa-fw"></i> **二維的基本宣告**
```python=
a=[[1,2,3],[2,3,4]]
```
:question: 誒那==二維空列表==要怎麼設定啊?**跟下一題超級有關!**
>請大家看以下面兩種宣告:
```python=
c = [[0 for i in range(2)] for j in range(3)]
print(c)
c=[[0]*2]*3
print(c)
```
>如果這時候加入`c[0][0]=77` 想一想會發生什麼事情?

:::warning
小練習2 **(二維練習)**:zap:
完成 3X3 矩陣和 3X2 整數矩陣的乘法,輸出結果矩陣。
* *範例:*
* 第一個矩陣3X3
3 2 1
5 6 7
2 4 6
* 第二個矩陣3X2
2 3
3 4
6 2
* *輸入與輸出格式如下*
* **【樣例輸入】**
3 2 1
5 6 7
2 4 6
2 3
3 4
6 2
* **【樣例輸出】**
18 19
70 53
52 34
:::
---
## tuple 元組
操作原理大致上和list差不多
用()來建立Tuple
list轉tuple()
EX:`tuple([1,2,3])` =>(1,2,3)
<i class="fa fa-pencil fa-fw"></i> **tuple 的基本宣告**
```python=
my_list=[1,2]
my_tuple=(1,2)
other_tuple=3,4 #不加括號其實也可以只是不推薦
print(other_tuple)
my_list[1]=3
print(my_list)
try:
my_tuple[1]=3
except TypeError:
print("tuple內容不能改喇QQ")
```



<i class="fa fa-pencil fa-fw"></i> **tuple 基本運算**
```python=
tuple1=('minions',7,True,3.15926)
tuple2=(False,20)
print("tuple1[1:]=", tuple1[1:]) #slice基本上跟list一樣
print("tuple2[0]=", tuple2[0])
#雖然不能改變tuple內容,但是仍然可以取其值進行運算
print(tuple1+tuple2)
print(tuple1[1]+3)
print(tuple2*3)
```



:bulb:如果 function 需要==回傳多個數值==, 此時 tuple 就會非常方便~
<i class="fa fa-pencil fa-fw"></i> **用 tuple 回傳數值**
```python=
def sumNproduct(a,b):
return (a+b), (a*b)
sp=sumNproduct(2,3) #sp= (5,6)
s,p = sumNproduct(2,3) #s=5 , p=6
```
### Tuple vs. list
* 沒有insert()、append() 等function
* ==tuple建立後就不能修改裡面的內容==
* 可以當dictionary的key(下面會提到)
### 一些tuple還是能用的函式(不涉及內容刪改)
* `len(tuple)`:回傳tuple長度
* `max(tuple)`:回傳tuple中的最大值
:bulb: 簡單來說 tuple 跟 list 的操作方式重疊度真的很高~只要不涉及內容刪改, tuple 基本上都可以用, 大家有時間可以玩玩看~^^
:::warning
小練習3 **(tuple)**:zap:
隨意輸入一串數字,如:nums = [2, 7, 11, 15, 1, 8, 6 ,10]
請找到**任意相加為9**的元素集合,如:[(2, 7), (1, 8)]
* **【樣例輸入】**
1 2 3 4 5 6 7 8 9 0 10 -1
* **【樣例輸出】**
[(1, 8), (2, 7), (3, 6), (4, 5), (9, 0), (10, -1)]
:::
---
## dict 字典
另一種基本的資料結構,它包含了**鍵值( key )** 以及對應的**值( value )**,讓我們可以快速選出某個key對應的value **~~(我一直不能明白為什麼它叫字典)~~**
我們利用{}來建立Dictionary
`dictionary={'key1':'value1','key2':'value2',...,'keyn':'value
n'}`
- [x] dictionary :你的字典名稱
- [x] key1, key2,..., keyn :元素的鍵值,==**必須是唯一而且不可更動的**==, 型態可以是 int, str 等等
- [x] value1, value2, ..., valuen :表示元素的值
<i class="fa fa-pencil fa-fw"></i> **dict的基本宣告**
```python=
empty_dict={} #空字典建立
empty_dict2=dict() #其實也可以但是不推薦
#key 為整數的字典
puipui={1:'馬鈴薯',2:'西羅摩',3:'阿比',4:'泰迪', 5:'巧克力'}
print(puipui)
print(puipui[1])
```


<i class="fa fa-pencil fa-fw"></i> **dict小練習 #key為文字的字典**
```python=
grades={'Wendy': 98,'Emilia': 82, 'Darren': 70}
darren_grade=grades['Darren']
print("Darren=", darren_grade)
#如果你用了一個不存在的key 就會出現keyError的情況...
try:
howard_grade = grades['Howard']
except KeyError:
print("no grade for Howard ^^")
#可以再次利用 in 確定你的 key 484存在的
darren_has_grade = 'Darren' in grades
print('darren_has_grade:', darren_has_grade)
howard_has_grade = 'Howard' in grades
print('howard_has_grade:', howard_has_grade)
#如果要指定特定的key或是value 請用中括號
grades['Darren'] = 90 #替換掉舊value
grades['Howard'] = 80 #添加新的項目
print(grades)
```




:bulb: **key**的值也可以是tuple喔~
```python=
NCTU_map = {(0,0):"浩然圖書館",(0,-4):"綜一",(3,0):"管一"}
```
---
### 一些dict的好用的函式
* `dict1.update(dict2)`:將一個字典的鍵與值複製到另一個,如果存在鍵相同,則以新傳入的值會蓋掉原本的值
* `dict.get('key')`:回傳字典中該鍵的值
* `dict.keys()`:回傳字典中所有的鍵
* `dict.values()`:回傳字典中所有的值
* `dict.items()`:回傳字典中所有的鍵值對
* `'key' in dict`:確認鍵是否存在字典中,回傳一個布林值
* `del dict['key']`:刪除字典中該鍵與值
* `dict.clear()`:清除字典所有內容

:::warning
小練習4 **(dictionary)**:zap:
讓我們來算算麥當勞餐點的熱量吧~
如果今天選擇只有大麥克、中薯、可樂、一份(四塊)麥克雞塊。請計算餐點熱量。
* **【呈現方式(截圖)】**

* 小提示:
```python=
dict={1:["Big Mac",530], 2:["Fries(Regular)",330],3:["Cola(Regular)",210],4:["McNuggets(4 pieces)", 230]}
number= list(dict.keys())
price = list(dict.values())
count_kcal=0
for i in range(4):
print(str(number[i])+price[i][0])
```
:::
:point_right:[今天的解答](https://hackmd.io/PKq9LblLSBKnDUrPgk6e3g)