1. 程式人生 > 其它 >可迭代物件&迭代器物件&for迴圈本質

可迭代物件&迭代器物件&for迴圈本質

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. 可迭代物件

  1. 什麼叫迭代:
    1. 即更新換代,每次的更新都必須依賴於上一次的結果
    2. 主要用於取值。
    3. 迭代給我們提供了一種,不依賴於索引取值的方式。
  2. 可迭代物件
    1. 內建有__iter__方法的,都稱之為可迭代物件
    2. 針對雙下劃線開頭,雙下劃線結尾的方法,最為專業標準的讀法為:“雙下方法名”,“雙下iter”。
    3. 內建的意思是可以通過.方法檢視的。
    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. 迭代器物件

  1. 迭代器物件
    既含有__iter__方法,又含有__next__方法
  2. 如何生成迭代器物件
    將可迭代物件執行__iter__方法
  3. 檔案物件本身既是可迭代物件,又是迭代器物件
  4. 迭代器物件無論執行了多少次__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 異常捕獲

  1. 什麼是異常??
    程式碼執行出錯,會導致異常,異常發生後,如果沒有解決方法,則會導致整個程式結束。

  2. 異常的三個重要組成部分:

    1. 異常的追蹤資訊traceback
      翻到錯誤的最下面,從下往上第一個藍色字型滑鼠左鍵點選,即可跳轉到錯誤程式碼所在行。
    2. 異常的型別
      xxxxError
    3. 異常的原因
      異常的型別冒號後面的內容。
      錯誤的詳細原因很重要。
      看完之後可能找到解決的方法。
  3. 錯誤的種類

    1. 語法錯誤
      不被允許的,出現了就立刻修改!!
    2. 邏輯錯誤
      可以被允許,出現之後儘快修改即可
      修改邏輯錯誤的過程,其實就是在從頭到尾清理思路的過程。
      NameError
      IndexError
      KeyError
      ValueError
      ...等等
  4. 捕獲異常的基本語法結構

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