目錄:http://m.itdecent.cn/p/863c446364a8
一、迭代
1、迭代:
在Python中,如果給定一個list或tuple,我們可以通過for循環(huán)來遍歷這個list或tuple,這種遍歷我們成為迭代(Iteration)。
2、可迭代對象:
(1)、定義
字面意思:可以進(jìn)行循環(huán)更新的一個實(shí)實(shí)在在的值。
專業(yè)角度:內(nèi)部含有'__iter__'方法的對象。
我們之前學(xué)過的可迭代對象有:列表、字符串、元組、字典,集合、range、文件。
(2)、獲取對象的所有方法并且以字符串的形式表現(xiàn):dir()
st1="python"
li1=[1,2,3]
print(dir(st1))? ? ? ? ? ? ? #這是將會運(yùn)行出st1所有的方法
print(dir(li))
(3)、判斷一個對象是否是可迭代對象
st1="python"
print('__iter__' in dir(st1))? ? #判斷st1是否為可迭代對象
print('__iter__' in dir(range(10)))? ? ? #判斷range(10)是否為可迭代對象
運(yùn)行結(jié)果為:
True
True? ? #當(dāng)對象為可迭代對象是返回True
或者
from?collections import Iterable? #判斷之前需導(dǎo)入內(nèi)置庫
s='hello'
print(isinstance(s,Iterable))?????? #判斷是不是可迭代對象
運(yùn)行結(jié)果為:
True
(4)、可迭代對象的優(yōu)缺點(diǎn)
優(yōu)點(diǎn):
1、存儲的數(shù)據(jù)直接能顯示,比較直觀。
2、擁有的方法比較多,操作方便。
缺點(diǎn):
1、占用內(nèi)存
2、不能直接通過for循環(huán),不能直接取值(索引,key)
二、迭代器
1、定義:
內(nèi)部含有'__iter__'方法并且含有'__next__'方法的對象就是迭代器。
2、判斷是否為迭代器:
'__iter__'and '__next__'在不在dir(對象)(我們之前學(xué)過的迭代器只有文件)
f=open("1.txt","r")
print('__iter__'in dir(f)and '__next__'in dir(f))
運(yùn)行結(jié)果為:
True
3、可迭代對象可以轉(zhuǎn)換為迭代器
st1="python"
obj=iter(st1)? ? ?#將st1轉(zhuǎn)換為迭代器
print(obj)? ? ? ? ? ?#輸出的結(jié)果是字符串迭代器對象的地址
運(yùn)行結(jié)果為:?
<str_iterator object at 0x03716CB0>
##當(dāng)st1為迭代器時就可以用'__next__'方法了
print(next(obj))? #注意這時是把obj作為一個迭代器,并不是st1,st1還是可迭代對象。
運(yùn)行結(jié)果為:
p? ? #運(yùn)行一次next方法就輸出一次字符,直到字符串中所有字符全部輸出時,再
次運(yùn)行就會報錯。
print(next(obj))?
print(next(obj))?
print(next(obj))?
print(next(obj))?
print(next(obj))? ??? #這時字符全部輸出
print(next(obj))? #這時在print時就會報錯
報錯為:
print(next(obj))
StopIteration
4、遍歷可迭代對象和遍歷迭代器的區(qū)別:
#可迭代對象
li=[1,2,3,4,5,6,7,,8,9,10]
count=0
for i in li:
????if count ==4:
? ? ? ? break
? ? else:
? ? ? ? print(i)
? ? count +=1
count=0
for i in li:
????if count ==6:
break
else:
print(i)
? ? count +=1
運(yùn)行結(jié)果為:
1 2 3 4 1 2 3 4 5 6
#迭代器
li=[1,2,3,4,5,6,7,,8,9,10]
obj=iter(li)
for i in range(4):
? ? print(next(obj))
for i in range(6):
????print(next(obj))
運(yùn)行結(jié)果為:
1
2
3
4
5
6
7
8
9
10
當(dāng)我們遍歷可迭代對象時,每一次循環(huán)都會開頭遍歷。而當(dāng)我們遍歷迭代器時,會接著上次執(zhí)行到的位置再次執(zhí)行。
5、迭代器的優(yōu)缺點(diǎn):
優(yōu)點(diǎn):
1、節(jié)省內(nèi)存
2.、惰性機(jī)制,next一次,去一個值。
缺點(diǎn):
1、速度慢
2、不走回頭路
6、迭代器和可迭代對象的對比:
可迭代對象是一個操作方法比較多,比較直觀,存儲數(shù)據(jù)相對少的一個數(shù)據(jù)集。
當(dāng)你側(cè)重于對于數(shù)據(jù)可以靈活處理,并且內(nèi)存空間足夠,將數(shù)據(jù)集設(shè)置為可迭代對象是明確的選擇。
迭代器是一個非常節(jié)省內(nèi)存,可以記錄取值位置,可以直接通過循環(huán)+next方法取值,但是不直觀,操作方法比較單一的數(shù)據(jù)集。
當(dāng)你的數(shù)據(jù)量過大,大到足以撐爆你的內(nèi)存或者你以節(jié)省內(nèi)存為首選因素時,將數(shù)據(jù)集設(shè)置為迭代器是一個不錯的選擇。
7、while模擬for的內(nèi)部循環(huán)機(jī)制:
? ?for循環(huán)的循環(huán)對象一定要是可迭代對象,但是這不意味著可迭代對象就可以取值,因?yàn)閒or循環(huán)的內(nèi)部機(jī)制是:將可迭代對象轉(zhuǎn)換成迭代器,然后利用next進(jìn)行取值,最后利用異常處理處理StopIteration拋出的異常。
l1 = [1, 2, 3, 4, 5, 6]
# 1 將可迭代對象轉(zhuǎn)化成迭代器
obj = iter(l1)
# 2,利用while循環(huán),next進(jìn)行取值
while 1:
? ? # 3,利用異常處理終止循環(huán)
? ? try:
? ? ? ? print(next(obj))
? ? except StopIteration:
? ? ? ? break