owned this note
owned this note
Published
Linked with GitHub
---
title: 容器 - Python 教學
description: 中興大學資訊研究社1091學期程式分享會主題社課
tags: Python
---
#### meet.google.com/czn-pbav-zvr
### md.nchuit.cc/py/
# 容器+流程控制
> [name=ZJ][time= 110,10,11]
[toc]
---
# 容器
翻譯
| `int` | `float` | `str` | `bool` |
| ----- | ------- | ----- | ------ |
| 整數 | 浮點數 | 字串 | 布林值 |
| `list` | `dict` | `tuple` | `set` |
| ------ | ------ | ------- | ----- |
| 串列 | 字典 | 元組 | 集合 |
---
## 串列 (List)
List 在 Python 中常常用來儲存連續性的資料,在使用上與 C/C++ 中的 **陣列(array)** 有許多相似之處。
不過**list**這個字本身就是不包含長度的意思,在建立之初不用(也不可以)宣告長度,用實際物品比喻的話可以理解為單字卡(下圖)
>btw 如果想出建立有初始長度的請搭配generator使用

並且能藉由自帶的功能(methon)來實現元素的新增或移除
---
Python 建立 List 時以中括號將元素包起來,<br>值得一提的是:List 能將 **不同型態** 的資料放在一起
```python
example = [123, 'word', True, [], {}]
```
| 索引 | example |
| ---- | -------- |
| 0 | `123` |
| 1 | `'word'` |
| 2 | `True` |
| 3 | `[]` |
| 4 | `{}` |
---
## 字典 (Dictionary)
Dictionary 與 List 的區別就只是包著的符號改成大括號、需要特別宣告 ***鍵值(key)*** 而已。
```python=
example = {4:123, 2:'word', 0:True}
```
| 索引 | example |
| ---- | -------- |
| 4 | `123` |
| 2 | `'word'` |
| 0 | `True` |
---
### `dict`補充說明
``dict`` 是 **無序** 的。
``dict`` 的 ***鍵值(key)*** **只可以**是<br>``int``, ``str``, 或 ``tuple``
```python=
ex1 = {3:[], 27:[]} # key 為 int 的 dict
ex2 = {'m':[], 'l':[]} # key 為 str 的 dict
ex3 = {(7,9):[], (4,2):[]} # key 為 tuple 的 dict
```
---
#### 資料型態 `tuple, set` 補充
`tuple, set` 類似 `list` 什麼都能塞,但
```python=
t = (1,'words',False) # tuple 不能變動
s = {0.0,True,'luv'} # set 無法取 index
```
---
##### 延伸
`tuple, set, list` 可以互相 **轉型**
```python=
t = (1,'words',False)
s = {2.0,True,'luv'}
l = [False,0,'abc']
#下面隨便看看就好,傷眼睛
ts = tuple(s) #ts = (2.0,True,'luv')
tl = tuple(l) #tl = (False,0,'abc')
st = set(t) #st = {1,'words',False}
sl = set(l) #sl = {False,0,'abc'}
lt = list(t) #lt = [1,'words',False]
ls = list(s) #ls = [2.0,True,'luv']
```
---
::: spoiler 練習
```python=
ex = {'a':(True, False), 'b':[3, 2, 7]}
print(ex['b'][2]) #輸出: 7
```
---
:::
建立一個包含<br>全是 `int` 的 `list` 和全是 `bool` 的 `tuple`、<br>索引值為 `str` 的 `dict`
| 索引 | ex |
| ---- | ------------- |
| a | `(True, False)` |
| b | `[3, 2, 7]` |
---
## 元素存取
``list, dict`` 中要存取其中的某一筆資料,直接在後面加上 ``[index]`` 即可
```python=
e = ['word', 123, False]
print(e[0]) # list 索引值從 0 開始
#輸出: word
d = {'m':420,'w':327,'d':105}
print(d['w']) # 字串索引 dict 取元素需打上''
#輸出: 327
```
補充: `str` 取索引值會取得位於該索引值上的字元
```python=
w = 'lth'
print(w[2])
#輸出: h
```
---
``list`` 中如果取 index 為 -1 即為 ``list`` 中最後一個元素
```python=
e = ['word', 123, False]
print(e[-1])
#輸出: False
print(e[-2])
#輸出: 123 ...依此類推
```
注意: index 取負號只限 `list` 或 `tuple`
---
## 元素變換
### 範例
```python=
e = ['word', 123, False]
e[-1] = 2.0
print(e)
#輸出: ['word', 123, 2.0]
d = {'m':420,'w':327,'d':104}
d['d'] += 1 #在原有的數字上+1
print(d)
#輸出: {'m':420,'w':327,'d':105}
```
---
::: spoiler 練習
將字串:`'hello'`取代為 `list:['hello']`
```python=
ex[0] = ['hello']
```
---
:::
試試看 在以下程式碼中間加一行使輸出為 hello
```python=
ex = ['hello', 123, False]
#加在這
print(ex[0][0])
#原輸出: h
```
---
## `list` 取範圍
List 中還有一個特性就是能指定範圍。
使用中括號 ``[a:b]`` 即為 `list` 索引值 a~b 的部分,如
```python=
list_example=['0',1,'2',3,'4',5,'6']
print(list_example[2:-1]) #[:-#]有別於[-#:]、[-#]
#輸出:['2', 3, '4', 5]
```
---
### 補充
取範圍還有其他特定位置的用法,如
省略起始: ``[:9]``$\iff$``[0:9]``
省略結尾: ``[1:]``$\iff$``[1:len(list)]``
取範圍同樣適用 ``str, tuple``,但 `tuple` 只能取、不能動。另因為 `dict` 無序,無法取範圍。
``len()``
: 取得``list``有幾個元素、或``dict``有幾組資料
---
::: spoiler 練習
```python=
print(ex[-4:]) #輸出: hijk
print(ex[:5]) #輸出: abcde
print(ex[1:-4]) #輸出: bcdefg
```
---
:::
試對字串 `ex` 取範圍
```python=
ex = 'abcdefghijk'
```
輸出
```
hijk
abcde
bcdefg
```
---
## `list` 新增元素
### 1.`append(object)`
`append()` 能將資料新增在list 的結尾
格式: `append(`你要插入的資料`)`
```python=
e = list() #同 e = []
e.append(3.27)
e.append('x')
print(e)
#輸出[3.27, 'x']
```
---
### 2.`insert(int,object)`
`insert()` 能將元素插入指定位置
格式: `insert(`你要插入的index`,`你要插入的元素`)`
```python=
e = [6, 'x', 9, 'y']
e.insert(2,True)
print(e)
#輸出: [6, 'x', True, 9, 'y']
```
---
## `dict` 新增元素
`dict` 中新增元素需要搭配鍵值(key/index)新增,方法有兩種
```python=
d = dict() #同 d = {}
#方法1: 取想新增的索引值後賦值,常用
d['d'] = 105
#方法2: 運用setdefault()成對塞進去,限鍵值不存在時使用
d.setdefault('x', True)
print(d)
#輸出: {'d': 105, 'x': True}
```
---
### `setdefault()` 延伸
```python=
d = dict()
# setdefault() 常用來新增 list 或 set 後進行操作
d.setdefault('e',[4.2]).append(3.27)
d.setdefault('s',{7.1}).add(105)# set 新增元素用 add()
print(d)
#輸出: {'e': [4.2, 3.27], 's': {105, 7.1}}
test = d.setdefault('e') #有了鍵值之後後面打啥都沒用
print(test) # 看看這是什麼
#輸出: [4.2, 3.27]
print(d['e']) # 再看看這是什麼
#輸出: [4.2, 3.27]
```
---
::: spoiler 練習
```python=
d['a'].insert(1,'C')
d['a'].append('U')
d['b'] = 'IT' #或 d.setdefault('b','IT')
```
---
:::
不使用 元素變換,試將 `d` 透過 新增元素 變成 `dd`。
```python=
d = {'a':['N','H']}
#新增元素
dd = {'a':['N','C','H','U'], 'b':'IT'}
print(d,'' if(d == dd) else 'Wrong answer')
```
---
## 移除元素
### 1.`remove(object)`
使用 `remove()` 可以移除 `list` 中的指定資料
格式: `remove(`你要移除的資料`)`
```python=
e = ['0',1,'2',3]
e.remove('0')
e.remove(1)
print(e)
#輸出: ['2', 3]
```
注意
: `remove()` 適用 `list, set`,
另 `dict` 無法移除指定資料
---
### 2.`pop(int/str)`
`pop()` 可以根據輸入的 index 位置來移除元素
格式: `pop(`想移除元素的索引值/鍵值`)`
```python=
e = ['a',1,'2',3]
e.pop(2)
print(e)
#輸出: ['a', 1, 3]
e.pop() #list 中如果空白的話則會移除最後一個
print(e)
#輸出: ['a', 1]
```
---
另外 `pop()` 是能回傳值的,如
```python=
e = ['x',1,'2',3]
return_pop = e.pop(0)
print(return_pop)
#輸出: x
```
---
::: spoiler 練習
```python=
d['a'].pop() #或 pop(3) 或 remove('U')
d['a'].pop(1) #或 remove('C')
d.pop('b')
```
---
:::
不使用 元素變換,試將 `d` 透過 移除元素 變成 `dd`。
```python=
d = {'a':['N','C','H','U'], 'b':'IT'}
#移除元素
dd = {'a':['N','H']}
print(d,'' if(d == dd) else 'Wrong answer')
```
---
有趣的題外話:
JSON
```python=!
d={
'PlayName':'Mandy',
'BagItem':{
'sword':{
'LV':5,
'atk':2
},
'hat':{
'LV':10,
'def':3
}
},
'Equipment':{
'GM hat':{
'LV':1,
'def':999
},
'GM Gun':{
'LV':1,
'atk':999
}
}
}
```
---
## leetcode
https://leetcode.com/problems/linked-list-cycle/
https://leetcode.com/problems/reverse-linked-list/
---
# list dic 先這樣
# 流程控制
----
# 迴圈
---
## 前言
程式寫作時,我們常常需要重複執行某段程式,這時迴圈的使用就顯得很重要
當我們已知or可計算執行的次數時我們常用for迴圈
而當執行次數難以計算時,就比較適合用while迴圈
---
# for
用法:
for (一物件) in (所有物件) :
簡單來說 就是
```
for "自己取的變數名稱" in "list,taple....":
"你要執行的程式碼"
```
**PS:注意縮排**
----
我們每次執行 都會從 後面的 list **依序** 拿其中一個元素對他做處理
Q:那我只是單純的想做100次呢?
那就用"range()"
---
## for 範例1
for 後面接一個 range() 如
```python=
for i in range(5):
print(i)
# 0,1,2,3,4
```
----
### range
> class range(stop)
> class range(start, stop[, step])
用法
1. 單純設定一個停止的數
如range(30)
```python=
# 0,1,2,3,4,....29
```
----
2. 設定開頭和結尾
如range(5,30)
```python=
# 5,6,7,8,9,10...29
#是5到29
```
3. 設定開頭、結尾和每一次加多少(step)
如range(5,30,5)
```python=
# 5,10,15,20,25
```
當然數字不一定是要正的,負的也行
----
::: spoiler 練習1
```python=
k = int(input("input: "))
for i in range(k, -1, -1):
print(i, end=" ")
```
:::
輸入:n
輸出:n 到 0
ex:10,9,8,7,6,....0
hint:
注意range()的範圍
```python=
x = int(input()) #輸入一個數字,並轉為整數的型態
print(x) #輸出一個數字
```
----
:::spoiler 練習2
```python=
n = int(input())
fb_list=[]
for i in range(n):
if i == 0 or i == 1:
fb_list.append(1)
else :
fb_list.append(fb_list[-1]+fb_list[-2])
print(fb_list)
```
:::
輸入:n
輸出:F1~Fn 的費氏數列
ex:
input:6
output:1,1,2,3,5,8,
input:8
output:1,1,2,3,5,8,13,21,
hint:
```
用list存
```
---
### for 範例2
for 後面接一個list
舉例來說
```python=
list=[2,4,5,8,1,3]
for x in list:
print(x)
# 2,4,5,8,1,3
```
當然,不一定要都是相同的型態
```python=
list=['gawr','gura',1,0,0,'!']
for x in list:
print(x,end='')
```
----
::: spoiler 練習3
```python=
list_A=[1,2,3,54,4,4,6,8]
for i in list_A:
print(2*i, end=' ')
```
:::
給定
```python=
list_A=[1,2,3,54,4,4,6,8]
```
輸出:
兩倍的list_A
ex:
[2,4,6,108,8.....]
----
::: spoiler 練習3.5
```python=
list_B = [1,2,3,54,4,4,6,8]
list_C = []
for i in range(-1, -len(list_B)-1, -1):
list_C.append(list_B[i])
for i in list_C:
print(i, end=" ")
```
---
:::
給定
```python=
list_B=[1,2,3,54,4,4,6,8]
```
輸出:
新的list_C=list_B的反過來
ex:
[8,6,4,4,54,3,2,1]
>hint: Using "insert()" to add item in new list
---
### for 範例3
~~防風林外還有防風林外還有防林~~
for 迴圈中當然也還能有for 迴圈
而要怎麼判斷屬於哪層的for迴圈則是看縮排
```python=
list_G=[['x1','x2','x3'],['y1','y2','y3'],['z1','z2','z3']]
for dim in list_G:
for pos in dim:
print(pos)
```
----
上面這 第一個 dim指的是 list 中的 list
```python=
a=10
b=20
count=0
for i in range(a):
for j in range(b):
count += 1 #count = count + 1
print(count)
```
猜猜看會輸出多少?
因為內層的 for 執行了20次count+=1
而外層的 for 執行了內層的 for 10次
所以20*10=200
```python=
a=10
b=20
count=0
for i in range(a):
count+=1
for j in range(b):
count+=1
print(count)
```
那這樣是多少呢?
### 印星星
for 搭配 if
```python=
a=int(input("多高"))
listA=['gura',1,0,0,'!']
for x in listA:
print(x,end=' ')
print('')
for i in range(a):
if i==(int)(a/1.5):
for j in range(a+i+1):
if j>=a-i and j<=a+i+1:
print('*',end='')
else:
print(' ',end='')
else:
for j in range(a):
if j==a-i:
print('*',end='')
else:
print(' ',end='')
for j in range(i+1):
if j==i:
print('*',end='')
else:
print(' ',end='')
print('')
```
::: spoiler 練習4 (easy)
```python=
a=int(input())
for i in range(a):
for j in range(a):
print('*',end='')
print('')
```
---
:::
輸入 n
印出 n*n的正方形
ex:
input=3
output=
**\*
\*\*\*
\*\*\*
---
::: spoiler 練習5(hard 題目我抄來的)
```python=
a=int(input())
count=0
for i in range(a):
for j in range(1, i//2):
if (i%j)==0:
count+=1
if count==1:
print(i,end=',')
count=0
```
---
:::
輸入 n
印出 所有小於n的質數
ex:
input=15
output=2,3,5,7,11,13
---
#### 練習6(hard)
輸入 n
印出 半徑為n的圓形
you may need [sqrt()](https://www.runoob.com/python/func-number-sqrt.html) and [round()](https://www.runoob.com/python/func-number-round.html)
```python=
import math
r=int(input())
count=0
for i in range(2*r+1):
for j in range(2*r+1):
if (i-r)**2+(j-r)**2<=r**2 and (i-r)**2+(j-r)**2>=r**2 :
print('*',end='')
else:
print(' ',end='')
print('')
```
## while
whlie 通常用於我們不知道做幾次,但是知道甚麼時候該結束的事件
```python=
a=2
while(a<4096):
a*=a
print(a)
```
上面範例就是a一直平方直到a>=4096
```python=
a=1
k=' '
while(k):
k=input()
a+=1
print(a,k)
print('--end--')
```
這段程式碼則是會在k沒有輸入時停止
### break (can also use in for loop)
在執行到一半時,如果我們希望能直接跳出迴圈則使用break

break!
```python=
a=1
k=' '
while(k):
k=input()
if k=='exit':
break
a+=1
print(a,k)
print('--end--')
```
上面程式在k==exit時會直接跳出while loop
### continue (can also use in for loop)
```python=
a=1
k=' '
while(k):
k=input()
if k== 'pass':
continue
a+=1
print(a,k)
if k=='exit':
break
print('--end--')
```
::: spoiler practice 01
input 整數n ,n>0 請輸出 n 的二進位數
```python=
a=int(input())
output=''
while(a>0):
output=str(int(a%2))+output
a=a-(a%2)
a=a/2
print(output)
```
---
:::
ex:
input:4
output:100
input:15
output:1111
---
## 疑難雜症
### for x in list??
舉例來說
```python=
list=[2,4,5,8,1,3]
for x in list:
print(x)
# 2,4,5,8,1,3
```
不過這邊的運算大概是這樣
```python=
list=[2,4,5,8,1,3]
for i in range(len(list)):
x=list[i]
print(x)
```
.
.
.
.
```python=
a=[-1,2,-3,-4,5,6,7,-8,9,-10,11]
for x in a:
x+=10
print(a)
```
對x的操作只影響x
不影響list
.
.
.
```python=
a=[-1,2,-3,-4,5,6,7,-8,9,-10,11]
for x in a:
if x<0:
a.remove(x)
print(a)
```
```python=
a=[-1,2,-3,-4,5,6,7,-8,9,-10,11]
for x in a[:]:
if x<0:
a.remove(x)
print(a)
```
如果對list直接操做要注意是否會影響跌代的結構
# 補充
for 迴圈其實是呼叫一個迭代器
[Python進階技巧 (6) — 迭代那件小事:深入了解 Iteration / Iterable / Iterator / \_\_iter__ / \_\_getitem__ / \_\_next__ / yield](https://medium.com/citycoddee/python%E9%80%B2%E9%9A%8E%E6%8A%80%E5%B7%A7-6-%E8%BF%AD%E4%BB%A3%E9%82%A3%E4%BB%B6%E5%B0%8F%E4%BA%8B-%E6%B7%B1%E5%85%A5%E4%BA%86%E8%A7%A3-iteration-iterable-iterator-iter-getitem-next-fac5b4542cf4)
所以可以透過自訂迭代邏輯來客製化迴圈
ex:
```python=
class MyIterator:
def __init__(self):
self.total_times = 0
self.index = 0
def add_times(self, times):
self.total_times += times
return self
def __iter__(self):
return self
def __next__(self):
self.index += 1
if self.index <= self.total_times:
return self.index
else:
self.index -= 1
raise StopIteration
my_iterator = MyIterator()
for item in my_iterator.add_times(3):
print(item)
for item in my_iterator.add_times(3):
print(item)
for item in my_iterator:
print(item)
```
# leetcode?
https://leetcode.com/problems/two-sum/
https://leetcode.com/problems/add-two-numbers/
https://leetcode.com/problems/climbing-stairs/
----
#### 填個[回饋單](https://forms.gle/vr8panG1mi59t49v7)複習一下吧
[](https://forms.gle/vr8panG1mi59t49v7)
<style>hr{display:none;}</style>