可迭代物件&迭代器物件&for迴圈本質
阿新 • • 發佈:2021-11-19
1. 常用內建函式
""" 其中幾個方法得到的結果型別是迭代器物件的型別, 所以想要打印出內容,必須用for迴圈或者其他容器型別包裹,如下例子: res = zip(l1,name_list) print(list(res)) res1 = zip(l1,name_list,l2,l3) for i in res1: print(i) """ # 1. map() # 對映 l = [1,22,333] print(list(map(lambda x: x+1, l))) # 迴圈獲取列表中每個元素並傳遞給匿名函式儲存返回值 # map方法詳細介紹地址 # 在這裡:https://www.cnblogs.com/Joshua-jiaxue/p/15573256.html#_label4 # 2.zip() 拉鍊 l1 = [1,2,3,4] name_list = ['jason','jack','joshua','jerry'] l2 = [33,52,53,56,3,2,67] l3 = [234,435,56,345,763,33] # 要求將索引相同的元素配對 res = zip(l1,name_list) print(list(res)) res1 = zip(l1,name_list,l2,l3) for i in res1: print(i) # 3.max(),min() l4 = [13,21,36,42,58,79,60,3,22] print(max(l4)) # 79 print(min(l4)) # 3 dic = { 'jason': 2000, 'jack': 4000, 'joshua':1000, 'jerry':3000 } # 想要獲取工資最高的人 print(max(dic)) # joshua # 由於根據key的字母ASCII的大小排序,所以得不到正確的結果。 # max還支援傳入函式 print(max(dic, key=lambda x:dic[x])) # jack # 4.filter # 過濾 l5 = [12,23,34,45,67,88] res2 = filter(lambda x: x > 40, l5) print(list(res2)) # 5.reduce 歸總 # 將多個元素變成單個元素 from functools import reduce l6 = [12,14,22,43,56,66,88,99] res3 = reduce(lambda x,y: x+y, l6) print(res3) # 400 res4 = reduce(lambda a,b: a+b, l6, 50) # 還可以額外新增值 print(res4) # 450
2. 可迭代物件
- 什麼叫迭代:
- 即更新換代,每次的更新都必須依賴於上一次的結果
- 主要用於取值。
- 迭代給我們提供了一種,不依賴於索引取值的方式。
- 可迭代物件
- 內建有
__iter__
方法的,都稱之為可迭代物件 - 針對雙下劃線開頭,雙下劃線結尾的方法,最為專業標準的讀法為:“雙下方法名”,“雙下iter”。
- 內建的意思是可以通過
.
方法檢視的。
i = 12 f = 1.12 s = 'jack' l = [1,2,23,4] d = {'name':'jack','age':18} t = (1,2,3) se = {11,22,33,44} b = True file = open(r'a.txt','w',encoding='utf8') 我們可以測試下哪些有__iter__方法。 """ 含有__iter__的有 字串,列表,字典,元組,集合,檔案物件 所以上述都可以稱為可迭代物件。 """ print(d.__iter__()) # 類似於d.get() print(iter(d)) # 結果與上面一致 print(d.__len__()) print(len(d)) """ 可迭代物件呼叫了__iter__方法後,會變成迭代器物件。 且 __iter__在呼叫的時候簡便寫法iter() 一般情況下所有的雙下方法都有一個簡寫:方法名()加括號。 """
- 內建有
3. 迭代器物件
- 迭代器物件
既含有__iter__方法,又含有__next__方法 - 如何生成迭代器物件
將可迭代物件執行__iter__方法 - 檔案物件本身既是可迭代物件,又是迭代器物件
- 迭代器物件無論執行了多少次__iter__方法,結果還是迭代器物件(本身)
i = 12 # 全沒有 f = 1.12 #全沒有 s = 'jack' # 有iter l = [1,2,23,4] # 有iter d = {'name':'jack','age':18} # 有iter t = (1,2,3) # 有iter se = {11,22,33,44} # 有iter b = True #全沒有 file = open(r'a.txt','w',encoding='utf8') # 同時有iter和next res = s.__iter__() # 此時res有了__next__方法 # print(res.__next__()) # j # 迭代器物件執行__next__方法其實就是在迭代取值(for迴圈) # print(res.__next__()) # j # print(res.__next__()) # a # print(res.__next__()) # s # print(res.__next__()) # o # print(res.__next__()) # n # print(res.__next__()) # 再取報錯stopiteration """易錯點!!!!!!""" 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 # 每次得到的結果都是username,而不會報錯
4. for迴圈的本質
4.1 for迴圈內部原理
l1 = [1,2,3,4,5,6,7,8,9,10,11,22,33,44,55,66]
# 迴圈打印出列表中每個元素,但是不能使用for迴圈
# 1.先將列表轉為迭代器物件
res = l1.__iter__()
while True:
print(next(res))
# 取完值後會報錯:StopIteration
"""
for迴圈內部原理
1.將關鍵字in後面的資料先呼叫__iter__方法,轉為迭代器物件。
2.迴圈執行__next__方法
3.取完值後__next__會報錯,但是,
for迴圈會自動捕獲該錯誤,並處理。
res = 資料.__iter__()
while True:
監測程式碼是否報錯
res.__next__()
如果報錯則自動處理掉並結束while迴圈
"""
# 方法一:
# 統計次數,列表元素被列印完畢就停止迴圈
count = 0
num = len(l1)
while count < num:
print(next(res))
count += 1
"""重點在這裡"""
# 方法二:
異常捕獲,如下
4.2 異常捕獲
-
什麼是異常??
程式碼執行出錯,會導致異常,異常發生後,如果沒有解決方法,則會導致整個程式結束。 -
異常的三個重要組成部分:
- 異常的追蹤資訊traceback
翻到錯誤的最下面,從下往上第一個藍色字型滑鼠左鍵點選,即可跳轉到錯誤程式碼所在行。 - 異常的型別
xxxxError - 異常的原因
異常的型別冒號後面的內容。
錯誤的詳細原因很重要。
看完之後可能找到解決的方法。
- 異常的追蹤資訊traceback
-
錯誤的種類
- 語法錯誤
不被允許的,出現了就立刻修改!! - 邏輯錯誤
可以被允許,出現之後儘快修改即可
修改邏輯錯誤的過程,其實就是在從頭到尾清理思路的過程。
NameError
IndexError
KeyError
ValueError
...等等
- 語法錯誤
-
捕獲異常的基本語法結構
try:
有可能出現錯誤的程式碼
except 錯誤型別 as e:
出錯之後對應的處理機制(e是錯誤的詳細資訊)
except 錯誤型別 as e:
出錯之後對應的處理機制
except 錯誤型別 as e:
出錯之後對應的處理機制
try:
print(name)
except NameError as e:
print('變數名不存在', e)
# as e 可加可不加,看自己需求。
# 變數名不存在 name 'name' is not defined
# 在我們不知道可能出現的錯誤型別的時候
# 有萬能異常
try:
int('abc')
except Exception: # BaseException
print('啥錯都能解決。。。')
"""
異常捕獲句式和萬能異常
1.有可能會出現錯誤的程式碼才需要被監測
2.被監測的程式碼一定要越少越好
3.異常捕獲使用頻率越低越好
爬蟲程式中會經常用到。
"""
# 下面我們來解決上面的問題
l1 = [1,2,3,4,5,6,7,8,9,10,11,22,33,44,55,66]
# 迴圈打印出列表中每個元素,但是不能使用for迴圈
# 1.先將列表轉為迭代器物件
res = l1.__iter__()
while True:
try:
print(next(res))
except StopIteration:
print('列印完畢')
break