一、定義
1.iterator.(迭代器)
2.iterable.(可迭代的)
一般來說,可以被for循環的就是可以迭代的,迭代器一定可以迭代,但是可迭代的類型不一定是迭代器。
二、說明
1.有__iter__方法,說明可迭代
def shili1():print(dir([])) #告訴我列表擁有的所有方法print(dir(()))print(dir(''))print(dir(range(10)))ret=set(dir([]))&set(dir(''))&set(dir({}))&set(dir(range(10)))print(ret) #有一個'__iter__'
判斷一下這些類型有沒__iter__方法
print('__init__' in dir(int)) print('__init__' in dir(list)) print('__init__' in dir(dict)) print('__init__' in dir(set)) print('__init__' in dir(tuple)) print('__init__' in dir(enumerate)) print('__init__' in dir(range(10))) print('__iter__' in dir(int)) #false print('__iter__' in dir(bool)) #false print('__iter__' in dir(list)) print('__iter__' in dir(dict)) print('__iter__' in dir(set)) print('__iter__' in dir(tuple)) print('__iter__' in dir(enumerate)) print('__iter__' in dir(range(10)))
2.#setstate指定從那個位置開始取(一般是從0位開始)
一個可迭代的類型執行了iter之方法后的返回值就是一個迭代器
print(set(dir([].__iter__())) - set(dir([]))) # {'__setstate__', '__next__', '__length_hint__'}
3.示例1(可迭代的不一定是迭代器,迭代器一定可迭代)
print('*'*40) l=[1,2,3] iterator=l.__iter__() print(iterator.__next__()) #l內部沒有next方法,調用iter之后的返回值有next print(iterator.__next__()) #l內部沒有next方法,調用iter之后的返回值有next print(iterator.__next__()) #l內部沒有next方法,調用iter之后的返回值有next # print(iterator.__next__()) #報錯 # 不能被循環的: not iterable(不可迭代的) -> __iter__ ->只要含有iter就可迭代且都可以被for循環 -> 可迭代協議
4.創建一個iterator
#[].__iter__()拿到一個 #可迭代協議 #在for循環時先找__iter__方法,如果沒有就 #迭代器協議->內部含有next方法和__init__方法的就是迭代器 print('__iter__' in dir([].__iter__()))from collections import Iterable from collections import Iteratorprint(isinstance([],Iterator)) #isinstace判斷是否是。迭代器,迭代類型。列表不是迭代器,但是可迭代。 print(isinstance([],Iterable))class A:# def __init__(self):passdef __next__(self):pass #同時有next和init就是迭代器。next可以一個一個獲取值# def __iter__(self):pass #有iter就可用被迭代 a=A() print(isinstance(a,Iterable)) print(isinstance(a,Iterator))#只要是迭代器一定可迭代,可迭代的不一定是迭代器 #可迭代的.__init__()方法可以得到一個迭代器
三、作用
使用迭代器的好處是可以節省內存空間
#用迭代器的好處:從容器類型中一個一個的取值,會把所有值都取到 # 可以節省內存空間(迭代器并不會再占用一大塊內存,而是隨著循環,每次生成一個,每次next給一個 #range,文件句柄 #range-> print(range(100000000)) #range(0, 100000000) 得到可迭代對象,但此時并沒有生成數據 print(list(range(10000000000000))) #內存錯誤 print(list(range(10))) #[0,1,2,……,9]#f=open ->#沒有for循環,依然可以遍歷 l=[1,2,3,4] iterator=l.__iter__() while True:print(iterator.__next__())#雖然會報錯,但是也一個個輸出了 最后拋出StopIterator
?四、總結
1.雙下方法:很少直接調用的方法,一般通過其他語法觸發。
2.可迭代的——可迭代協議:含有__iter__的方法(‘__iter__' in dir(數據))
3.可迭代的一定可以被for循環
4.迭代器協議:含有__iter__方法和__next__方法
5.迭代器一定可迭代,可迭代的通過調用__iter__方法可以得到一個迭代器
6.迭代器的特點:
1)方便使用,且只能取所有的數據取一次。下次重新取。
2)節省內存空間(當前和取下一個數據)