Python->基礎語法#3 儲存容器、控制敘述、列表推導式

儲存容器
-串列 list 、元組 tuple 、集合 Set
串列 list []
| 計算 | 說明 |
|---|---|
| x in L | 判斷 x 是否在 L 中 |
| x not in L | 判斷 x 是否不在 L 中 |
| L + t | 連接 L 及 t |
| L * n, n * L | 將 L 重複 n 次連接 L 本身 |
| L[i] | 取得索引值 i 的元素 |
| L[i:j] | 取得索引值 i 到 j 的子序列 |
| L[i:j:k] | 取得索引值 i 到 j ,間隔 k 的子序列 |
| len(L) | 回傳 L 的元素個數 |
| min(L) | 回傳 L 中的最小值 |
| max(L) | 回傳 L 中 的最大值 |
| L.index(i) | 取得 L 中第一次出現 i 的索引值 |
| L.count(i) | 累計 L 中 i 出現的個數 |
L = [9, 5, 2, 7]
L
len(L)
L[0]
L[:] # [魚頭 : 尾前]
L[:2]
k=['庭','院','深','深','深','幾','許']
#深深深
k[2:5]
!pip install twstock
!twstock -b 2330 6223
import twstock
stock = twstock.Stock("2330")
stock.price
stock.price[-1]
| 計算 | 說明 |
|---|---|
| L[i] = x | 將索引值 i 的元素指派為 x |
| L[i:j] = t | 將索引值 i 到 j 的元素指派為 t , t 為迭代器 |
| del L[i:j] | 刪除索引值 i 到 j 的元素 |
| L[i:j:k] = t | 將索引值 i 到 j ,間隔 k 的元素指派為 t , t 為迭代器 |
| del L[i:j:k] | 刪除索引值 i 到 j ,間隔 k 的元素 |
| list comprehension | 列表推導式:運用運算式生成新的串列 |
#for 迴圈
for i in [1,2,3,4]:
print(i*i)
r = []
for i in range(10):
r.append(i*i)
r
a=[]
for i in range(100):
if i % 2 == 1:
a.append(i)
a
a = [ i for i in range(10)]
a
a = [ i
for i in range(10)
]
a
b = [ i*i for i in range(100) if i % 2 == 1]
b
%%timeit
a=[ i**2
for i in range(100)
if i % 2 ==1]
a
#列表推導式list comprehension
[x for x in L if x > 3]
#如以原本寫法如下
result = [] #先創空list
for x in L: #for迴圈逐一判斷
if x >3: #判斷條件
result.append(x) #符合的結果附加到result串列裡
print(result)
#sorted(iterable, *, key=None, reverse=False)
sorted_L = sorted(L , reverse=True)
sorted_L
L.index(2)
| 計算 | 說明 |
|---|---|
| list.append(x) | 將 x 附加到 list 的最後 |
| list.extend(x) | 將 x 中的元素附加到 list 的最後 |
| list.count(x) | 計算 list 中 x 出現的次數 |
| list.index(x[, i[, j]]) | 回傳 x 在 list 最小的索引值 |
| list.insert(i, x) | 將 x 插入 list 索引值 i 的地方 |
| list.pop([i]) | 取出 list 中索引值為 i 的元素,預設是最後一個 |
| list.remove(x) | 移除 list 中第一個 x 元素 |
| list.reverse() | 倒轉 list 中元素的順序 |
| list.sort([key[, reverse]]) | 排序 list 中的元素 |
元組 tuple ()
- 元組 tuple 屬於不可變 (mutable) 的序列 (sequence) 型別,是不可更改的,可進行以下序列通用的計算。
| 計算 | 說明 |
|---|---|
x in s | 判斷 x 是否在 s 中 |
x not in s | 判斷 x 是否不在 s 中 |
s + t | 連接 s 及 t |
s * n, n * s | 將 s 重複 n 次連接 s 本身 |
s[i] | 取得索引值 i 的元素 |
s[i:j] | 取得索引值 i 到 j 的子序列 |
s[i:j:k] | 取得索引值 i 到 j ,間隔 k 的子序列 |
len(s) | 回傳 s 的元素個數 |
min(s) | 回傳 s 中的最小值 |
max(s) | 回傳 s 中的最大值 |
s.index(i) | 取得 s 中第一次出現 i 的索引值 |
s.count(i) | 累計 s 中 i 出現的個數 |
t = 2, 4, 6, 8
type(t)
#更改會報錯
t[0] = 1
2 in t
集合Set {}
- 集合set使用大括弧圍起來,但沒有重複的元素,且無序的存放元素。可將集合視為無鍵的字典物件。
- 針對集合的
in操作速度非常快,資料量大時更適合。 - 不常用,但用在找出不重複的資料時好用。
s1 = {9,9,5,5,2,2,7,7}
s2 = {9,5,2,7}
s1 == s2
s1
# !pip install -Uq jieba
import jieba
text = """2022 iThome 鐵人賽
iThome 鐵人賽是 IT 圈的年度盛事,是推動台灣 IT 技術向上成長的重要力量!每年逾千名 IT 行內人透過鐵人賽「連續 30 天發表技術文章不中斷」,寫出一整年的成長與學習、爆發驚人的技術能量。
鐵人們在賽事中寫下的成果,深獲業界好評與肯定。在博碩文化與 iThome 攜手合作之下,從 2018 年開始,陸續出版了多位得獎者的作品,讓得獎的鐵人們得以分享他們的榮耀與成果,幫助更多的讀者群、發揮更大的影響力,並且在寫code的人生中,為自己寫下最珍貴的那一頁。
在 iThome 鐵人賽的 30 天挑戰中,參賽者每一天都必須努力趕在午夜 12 點前、克服萬難,按下【送出】鍵,更別說賽期中還有中秋、國慶兩大殺手連假。當你已經艱辛奮鬥,攀越學業、社交、職場、家庭等一座座山峰,不管是喘氣休息、還是正駐足欣賞當前美景,是否還有勇氣與毅力,繼續登頂?許多鐵人們回想參賽以來最大的收獲,往往就是「原來我做得到」。
越來越多 IT 人透過 iThome 鐵人賽展現自我,並自豪地將賽事成果列入自己的履歷(讓徵才企業垂涎不已)。不用高估世界,也不用低估自己,今年就和眾多 IT 同儕一起喚醒心中最強大的鐵人!再一步,世界就在你的腳下。"""
wordlist = jieba.cut(text,cut_all=False)
wordlist = [ seg for seg in wordlist ]
wordlist
wordset = set(wordlist)
wordset
'鐵人' in wordlist
%%timeit
'鐵人' in wordlist
%timeit '鐵人' in wordset
計算 |說明
-|-
x in s |判斷 x 是否在 s 中
x not in s |判斷 x 是否不在 s 中
s1 & s2 |且運算,取得 s1 與 s2 的交集,等於 s1.intersection(s2)
s2 \| s2 |或運算,取得 s1 與 s2 的聯集,等於 s1.union(s2)
s1 ^ s2 |對稱差運算,取得 s1 與 s2 的對稱差集,等於 s1.symmetric_difference(s2)
s1 - s2 |差運算,取得 s1 與 s2 的差集,等於 s1.difference(s2)
s1 < s2 |判斷 s1 是否為 s2 的真子集
s1 <= s2 |判斷 s1 是否為 s2 的子集,等於 s1.issubset(s2)
s1 > s2 |判斷 s2 是否為 s1 的真子集
s1 >= s2 |判斷 s2 是否為 s1 的子集,等於 s1.issuperset(s2)
len(s) |回傳 s 的元素個數
min(s) |回傳 s 中的最小值 , s 中的元素必須是相同型態
max(s) |回傳 s 中的最大值, s 中的元素必須是相同型態
- 由於 set 型態是可變的,因此有額外兩個新增與刪除元素的方法:
| 方法 | 說明 |
|---|---|
s.add(e) | 增加 e 為 s 的元素 |
s.remove(e) | 從 s 中刪除元素 e |
字典Dictionary
-
以
{}以及冒號:來分隔鍵與值,以創建字典物件 -
建立字典變數可利用大括弧,裡頭以
key:value為配對的資料項目,每一筆資料再以逗號區隔開,例如d1 = {one:"a", two:"b"} -
使用字典須注意, key 必須是不可變的資料型態,且不可重複,如數字、字串 (string) 等; value 沒有限制,因此有需要的話,使用串列 (list) 或字典皆可。
-
也可以利用字典型態的建構子 (constructor) 建立物件。
#NG
{ ["k","e","y"] : 9527}
- 字典、串列與JSON相似,用法可以相互參照
- 一個公車交通資訊API MOTC Transport API V2
- 一個產品資訊API
//
//取得產品列表(Get):/api/livejs/v1/customer/{api_path}/products
{
"status": true,
"products": [
{
"category": "產品分類 (String)",
"image": "產品圖片 (String)",
"id": "產品ID (String)",
"title": "產品名稱 (String)",
"origin_price": "產品原始價錢 (Number)",
"price": "產品銷售價錢 (Number)"
}
]
}
{"數學": [100, 90, 80, 70] }
score = {"Math": [183, 70], "English": [163, 45]}
score
{"one":"a", "two":"b"}
dict(one="a", two="b")
dict({"one":"a", "two":"b"})
dict(zip(("one", "two"), ("a", "b")))
dict([["one", "a"], ["two", "b"]])
- 字典物件可進行以下的運算
| 計算 | 說明 |
|---|---|
| d[key] | 從 d 中取得 key 的 value |
| d[key] = value | 指定 d 的 key 的值為 value |
| del d[key] | 刪除 d 的 key 值 |
| key in d | 判斷 key 是否在 d 中 |
| key not in d | 判斷 key 是否不在 d 中 |
| iter(d) | 回傳由 d 的 key 建立的迭代器 |
| len(d) | 回傳 d 的配對資料個數 |
- 字典物件的方法 (method)
| 方法 | 描述 |
|---|---|
| dict.clear() | 清空 dict 的所有配對資料 |
| dict.copy() | 回傳 dict 的拷貝 |
| classmethod dict.fromkeys(seq[, value]) | 由 seq 中的元素構成 key ,每個 key 都給相同的 value 值 |
| dict.get(key[, default]) | 從 dict 中取得 key 的 value ,若無此 key 則回傳 default , default 預設為 None |
| dict.items() | 回傳 dict_items 物件,使 key:value 儲存為序對,然後依序儲存在 dict_items 物件中 |
| dict.keys() | 回傳 dict_items 物件,使 key 依序儲存在 dict_items 物件中 |
| dict.pop(key[, default]) | 將 key 的 value 從 dict 移除,若無此 kay ,回傳 default |
| dict.popitem() | 從 dict 移除任意一組 key:value |
| dict.setdefault(key[, default]) | 如果 key 在 dict 中,回傳 value 值,反之,將 key:default 加入 dict 之中 |
| dict.update([other]) | 將 dict 以 other 更新 |
| dict.values() | 回傳 dict_items 物件,使 value 依序儲存在 dict_items 物件中 |
d1 = {'a' : 'C8763', "b" : [9, 5, 2, 7]}
d1
d1["b"]
d1["天線寶寶"]="你好"
d1
bike = [{"地點":"台中火車站","車位":0},{"地點":"高美濕地","車位":100}]
d1['b']
'b' in d1
del d1['b']
d1
d1.keys()
d1.values()
d1.items()
- 可以update方法將字典合併
d1.update({'b':[1,2,3] , 'c': 'ithome'})
d1 # 'b':[9,5,2,7]被覆寫掉了
Python控制敘述
條件判斷 if, elif, else
if True:
print("YES")
if 1:
print("YES")
%%timeit
if 8+9 is 17:
print("YES")
%%timeit
if 8+9 == 17:
print("YES")
鐵人幫第n日 = 20
鐵人幫文章篇數 = 19
if 鐵人幫文章篇數 - 鐵人幫文章篇數 <= 0:
print("快點寫! 連庫拉皮卡要下船了阿")
else:
print("不用趕稿我就讚!")
鐵人幫第n日 = 19
鐵人幫文章篇數 = 19
if 鐵人幫文章篇數 - 鐵人幫文章篇數 == 0:
print("快趕稿,別富奸阿!!!!")
elif 鐵人幫文章篇數 - 鐵人幫文章篇數 < 0:
print("斷更! 挑戰失敗")
else:
print("持續更新我就讚!")
迴圈
迴圈是程式語言的特徵,讓電腦協助你重覆執行某項判斷,主流用法就是for迴圈與while迴圈,另外python還有一個枚舉可以使用。
For迴圈
-
先來個for迴圈吧,基本上for迴圈常與list結合使用,也常配合
range()。for 指標 in 要判別的資料集:
執行項目
for i in range(10):
print (i, "is less than 10")
for x in range(10):
if x==3:
continue # go immediately to the next iteration
if x==8:
break # quit the loop entirely
print(x)
for i in range(5): #[0,1,2,3,4]
print(i)
五俗藍 = ["紅茶", "綠茶", "烏龍", "鐵觀音", "多多冰沙", "咖啡冰沙", "抹茶拿鐵"]
for i in 五俗藍:
print(i)
for i in range(len(五俗藍)): # 以len()取出串列內容個數
print(五俗藍[i])
補充 range()
-
range()是建構式(constructor),用來表示不可變(immutable)的數字序列,例如[0,1,2,3,4]。
-
通常配合for迴圈產生內容。
-
建構式比已經占用記憶體位置的list省空間。
range(start, stop[, step])
range(stop)
a = range(1,11,2)
a
#[1,3,5,7,9]
# a.start
a.step
a.index(5)
i = iter(a)
i
next(i)
[Do it] HW3 : 九九乘法表
- 試輸出以下樣式
2*1=02 2*2=04 2*3=06 2*4=08 2*5=10 2*6=12 2*7=14 2*8=16 2*9=18
3*1=03 3*2=06 3*3=09 3*4=12 3*5=15 3*6=18 3*7=21 3*8=24 3*9=27
4*1=04 4*2=08 4*3=12 4*4=16 4*5=20 4*6=24 4*7=28 4*8=32 4*9=36
5*1=05 5*2=10 5*3=15 5*4=20 5*5=25 5*6=30 5*7=35 5*8=40 5*9=45
6*1=06 6*2=12 6*3=18 6*4=24 6*5=30 6*6=36 6*7=42 6*8=48 6*9=54
7*1=07 7*2=14 7*3=21 7*4=28 7*5=35 7*6=42 7*7=49 7*8=56 7*9=63
8*1=08 8*2=16 8*3=24 8*4=32 8*5=40 8*6=48 8*7=56 8*8=64 8*9=72
9*1=09 9*2=18 9*3=27 9*4=36 9*5=45 9*6=54 9*7=63 9*8=72 9*9=81
?print
# Your Code Here:
enumerate()枚舉
假設我們要迭代list成員的名稱,並獲取list中每個成員的位置。可以用enumerate,又稱枚舉
[9,5,2,7]
{1:9, 2:5, 3:2 , 4:7}
for i, v in enumerate(五俗藍):
print(i,v)
while迴圈
-
while迴圈,除非成立才會跳出循環。
-
注意成為無窮迴圈。
-
適合不知道要重複執行多少次任務時。
初始值
while 條件式:
程式區塊
索引變化
x=0 #設定初始值
while x < 10: #條件判斷
print (x, "is less than 10") #執行陳述
x += 1 #初值增減 x=x+1
count = 0
while count < 6:
print('The count is:', count)
count += 1 #count=count+1
print ("Good bye!")
# continue
i = 1
while (i < 6):
i += 1 # i=i+1
if i%2 > 0: #1
continue
print(i)
# break
i = 1
while (1):
print(i)
i += 1
if i > 10:
break
*現學現賣之「金庫密碼」
password = '' #先設一個空字串讓程式知道
while password != "1234":
password = input("快點輸入密碼>>")
if password == '1234':
print("進來吧")
break
else:
print("密碼錯誤再來一次")
- 通常密碼會單獨儲存在另一個檔案,作為環境變數。
%%writefile config.py
# 金庫密碼
SERECT = '5678'
SERECT2 = '1111115678'
import config
password = '' #先設一個空字串讓程式知道
while password != config.SERECT:
password = input("快點輸入密碼>>")
if password == config.SERECT:
print("進來吧")
break
else:
print("密碼錯誤再來一次")
print(f"註: 密碼為 {config.SERECT}")
- [註]: 在 Colab 如果遇到重複寫入
config.py卻未更新參數時,請在選單[執行階段]選擇[重新啟動執行階段],再執行一次。
例外陳述
- 例外處理 (exception handling) 是利用 try 、 except 、 finally 及 else
- 所謂例外 (exception) 是指已知有可能發生的 錯誤 (error) ,像是開啟檔案,檔案卻不存在,或除數為 0 等等的情況。
1/0
result = None
try:
result = 1 / 0
except ZeroDivisionError:
result = 1/1
print("......")
print(result)
- try: 所有可能發生例外的程式碼都要放在try來嘗試是否有錯誤
- except: 後空一格接例外類別 (class) ,底下程式區塊做相對應的例外處理
- else:假設沒有例外發生的處理
- finally 是例外處理結束後,無論如何都會執行的部分(可有可無)
try: #需嘗試有無錯誤的程式區塊
a = 1 / 0
except: #錯誤的話則...(省略ZeroDivisionError錯誤類別描述)
a = 0
else: #未發生例外狀況則...
m1 = "未發生例外狀況,粉好沒事"
finally: #無論錯誤最後一定會執行的
print("例外判斷結束句")
print(a)
print(m1)
try: #需嘗試有無錯誤的程式區塊
a = 1 / None
except: #錯誤的話則...(省略ZeroDivisionError錯誤類別描述)
a = 0
else: #未發生例外狀況則...
m2 = "未發生例外狀況,粉好沒事"
finally: #無論錯誤最後一定會執行的
print("例外判斷結束句")
print(a)
print(m2)
練習:以try/except撰寫模組安裝
- 以try/except撰寫模組安裝,嘗試如果沒有安裝twswock模組(該模組介紹),則安裝該模組。
- 提示1: 先嘗試import模組,沒有的話則安裝在import模組。
- 提示2: 安裝模組用到
!pip install 模組指令。
# !pip install twstock
import twstock
#Please answer here
try:
import twstock
except:
!pip install twstock
import twstock
列表推導式
- 列表推導式(list comprehension)非常帥氣,可以用英文List Creation from For Loop來理解,用以創建具有篩選能力的迴圈,其結果存為list
使用 列表推導式
list1 = []
for i in range(10):
list1.append(i)
print(list1)
[ i for i in range(10) ]
list2 = []
for i in range(10):
if i%2>0:
list2.append(i)
print(list2)
[ i for i in range(10) if i%2 > 0]
[ i*i for i in range(10)]
[ i for i in range(10) if i%2>0 ]
使用列表推導式篩選字典
dict1 = {'國文':87, '英文':78, '韓文':101, '穿越文':178, '史豔文':999}
dict1
[ i for i in dict1 ]
dict1.keys()
dict1.values()
[ i for i in dict1.keys()]
[ i for i in dict1.values()]
[{k:v} for k , v in dict1.items()]
[k for k , v in dict1.items()]
dict1.items()
[ v for k,v in dict1.items() ]
[{k:v} for k , v in dict1.items()]