1. 程式人生 > 其它 >迭代器與異常捕獲

迭代器與異常捕獲

目錄

今日內容概要

  • 結合匿名函式一起使用的函式
  • 可迭代物件
  • 迭代器物件
  • 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. 異常捕獲使用頻率越低越好
"""