迭代器與異常捕獲
阿新 • • 發佈:2021-11-19
目錄
今日內容概要
- 結合匿名函式一起使用的函式
- 可迭代物件
- 迭代器物件
- for迴圈的內部本質
- 異常捕獲(跳過報錯繼續執行)
內容詳細
-
常用內建函式
1. map 對映 l = [1, 2, 3, 4] map(lambda x:x+1, l) # 迴圈獲取列表中每個元素並傳遞給匿名函式儲存返回值 print(list(map(lambda x:x+1, l))) # 列印匿名函式儲存的返回值 2. zip 拉鍊 l = [11, 22, 33, 44, 55, 66, 77] name_list = ['jason', 'kevin', 'tony', 'jerry'] l1 = [1, 2, 3, 4, 5, 6, 7] l2 = [8, 7, 6, 4, 3, 2, 1] res = zip(l, name_list, l1, l2) print(list(res)) # [(11, 'jason', 1, 8), (22, 'kevin', 2, 7), (33, 'tony', 3, 6), (44, 'jerry', 4, 4)] 以元素最少的資料集為主(木桶原理) 3. max 求最大值 min 求最小值 在列表中 l = [11, 22, 33, 44, 55, 66, 77] print(max(l)) # 77 最大值 print(min(l)) # 11 最小值 在字典中 d = { 'jason': 3000, 'Bevin': 1000000, 'Ascar': 10000000000, 'aerry': 88888 } print(max(d)) # 只會按照ASCLL程式碼表來比較最大值查詢 '''正確寫法一''' def index(key): return d[key] print(max(d,key=index)) '''正確寫法二''' print(max(d, key=lambda key: d[key])) 取最小值 print(min(d, key=lambda key: d[key])) 4. filter 過濾 l = [11, 22, 33, 44, 55] res = filter(lambda x: x > 30, l) # 只取符合條件的值 print(list(res)) # [33, 44, 55] 5. reduce 歸總 from functools import reduce d = [11, 22, 33, 44, 55, 66, 77, 88, 99] res = reduce(lambda x, y: x + y, d) res1 = reduce(lambda x, y: x + y, d, 100) # 595 還可以額外新增元素值與列表中元素相加 print(res) # 495 求所有資料之和
-
可迭代物件
# 迭代 迭代即更新換代 每次更新的內容都必須依賴於上一次的結果 '''迭代其實是給我們提供了一種可以不依賴索引取值的方式''' # 可迭代物件 內建有 _ _iter_ _ 方法的都稱之為可迭代物件 內建是可以通過.(點)語法的方式直接檢視到 ''' 針對雙下劃線開頭結尾的方法 專業讀法為: 雙下 方法名 在面向物件的時候為了與隱藏變數區分開 ''' eg: n = 1 while True: n+=1 # 迭代 print(n) l = [11, 22, 33, 44, 55, 66] n = 0 while n < len(l): print(l[n]) n += 1 # 迭代 i = 12 # 沒有 f = 11.11 # 沒有 s = 'jason' # 有 l = [111,22,33,4] # 有 d = {'username':'jason','pwd':123} # 有 t = (11,22,33) # 有 se = {11,22,33} # 有 b = True # 沒有 file = open(r'a.txt','w',encoding='utf8') """ 含有 _ _iter_ _ 的有 字串 列表 字典 元組 集合 檔案物件 上述通常為 可迭代物件 """ print(d) print(d.__iter__()) # 等價於呼叫了一個內建方法 d.get() print(iter(d)) # .__iter__()簡化版寫法 iter(d) print(d.__len__()) print(len(d)) # .__len__()簡化版寫法 len(d) """ 可迭代物件呼叫了 __iter__ 方法後 會變成迭代器物件(老母豬) __iter__ 方法在呼叫時還有簡化版寫法 iter() 一般情況下 所有的雙下方法都會有一個與之對應的簡化版本 方法名() """
-
迭代器物件
""" 迭代器物件 既含有__iter__方法 又含有__next__方法 如何生成迭代器 讓可迭代物件執行__iter__方法即可 檔案物件本身既是可迭代物件又是迭代器物件 迭代器無論執行多少次__iter__方法 還是迭代器物件(本身) """ # 迭代器是給我們提供了不依據索引 取值的方式 i = 12 # 沒有 f = 11.11 # 沒有 s = 'jason' # 有 l = [111, 222, 333, 444] # 有 d = {'username': 'jason', 'pwd': 123} # 有 t = (11, 22, 33) # 有 se = {11, 22, 33} # 有 b = True # 沒有 file = open(r'a.txt', 'w', encoding='utf8') s = 'jason' res = s.__iter__() # 轉成迭代器物件 print(res.__next__()) # j 迭代器物件執行__next__方法其實就是在迭代取值(for迴圈) print(res.__next__()) # a print(res.__next__()) # s print(res.__next__()) # o print(res.__next__()) # n d = {'username': 'jason', 'pwd': 123} res = d.__iter__() # 轉成迭代器物件 print(res.__next__()) # 迭代器物件執行__next__方法其實就是在迭代取值(for迴圈) print(res.__next__()) # pwd print(res.__next__()) # 取完元素之後再取會"報錯" 易錯 print(d.__iter__().__next__()) # username print(d.__iter__().__next__()) # username print(d.__iter__().__next__()) # username print(d.__iter__().__next__()) # username print(d.__iter__().__next__()) # username print(d.__iter__().__next__()) # username 無論取多少次也不會報錯 ''' 一定要注意 什麼時候是依次往下執行(基於了上一次的結果) 什麼時候是產生了新的(跟上一次的結果無關) '''
-
for迴圈的本質
l1 = [1,2,3,4,5,6,7,8,9,11,22,33,44,55]
# 迴圈打印出列表中每個元素 但是不能使用for迴圈 __next__() next()
# 1.先將列表轉為迭代器物件
res = l1.__iter__()
# 2.迴圈執行__next__取值
while True:
print(res.__next__())
# 相當於
for i in l1:
print(i)
"""
for 迴圈內部原理
1.將關鍵字in後面的資料先呼叫 __iter__方法轉為迭代器物件
2.迴圈執行__next__方法
3.取完值之後__next__會報錯 但是for迴圈會自動捕獲該錯誤並處理
"""
-
異常捕獲
# 虛擬碼體
"""
res = 資料.__iter__()
while True:
檢測程式碼是否會報錯
res.__next__()
如果報錯了則自動處理掉並結束while迴圈
"""
# 什麼是異常
程式碼執行出錯會導致異常 異常發生後如果沒有解決方案則會導致整個程式結束
# 異常三個組成部分
1. traceback
翻到報錯最下面 從下往上的第一個藍色字型 滑鼠點選 會跳轉至錯誤的程式碼所在的行
2. XxxError
錯誤的型別
3. 錯誤型別冒號後面的內容
是錯誤的詳細原因(錯誤重點 可參考來解決報錯)
# 錯誤的種類
1. 語法錯誤
不被允許出現 一旦出現自行立刻改正
2. 邏輯錯誤
可以被允許 出現了之後儘快修改
'''修改邏輯錯誤的過程 其實就是在從頭到尾理清思路的過程'''
# 報錯示例
print(idna) # NameError
l = [11,22,33]
print(l[100]) # IndexError
d = {'username':'jason'}
print(d['xxx']) # KeyError
int('abc') # ValueError
異常捕獲語法結構
"""
try:
有可能出錯的程式碼
except 錯誤型別 as e:
出錯之後對應的處理機制(e是錯誤的詳細資訊)
except 錯誤型別 as e:
出錯之後對應的處理機制(e是錯誤的詳細資訊)
except 錯誤型別 as e:
出錯之後對應的處理機制(e是錯誤的詳細資訊)
...
'''出現了不同的錯誤 可以走不同的處理結果'''
"""
try:
int('abc') # 報錯 ValueError: invalid literal for int() with base 10: 'abc'
except NameError as e:
print('變數名name不存在',e)
except ValueError: # 該報錯型別只會走這裡
print('值不是純數字')
# 萬能異常捕獲
try:
int('abc')
print(name)
l = [11]
l[100]
except Exception:
print('你來啥都行 無所謂')
'''不論報錯型別 同意執行錯誤處理方法'''
# 規定
"""
異常捕獲句式和萬能異常
1. 有可能出現錯誤的程式碼才需要被監測
2. 被監測的程式碼一定要越少越好
3. 異常捕獲使用頻率越低越好
"""