理解迭代器和可迭代對象


前言:

之前在迭代器、可迭代對象這一部分一直有些混淆,結合一些資料,表達我對這些概念的理解,未必都對,但是適合剛開始入手的朋友們從零開始理解


 

開門見山首先介紹可迭代對象和迭代器的通俗理解

  迭代器就是能被next()調用得到下一次迭代值的對象,迭代器不直接保存迭代的序列值,而保存得到下一次迭代值的算法

  可迭代對象就是能被iter()方法調用得到迭代器的對象,能進行for循環的必須是可迭代對象

 

for循環的底層實現原理:

  以下是一個for循環的格式

  for i in 可迭代對象:
    循環體

  實質是調用內建方法iter()得到迭代器對象,然后通過每次調用next(迭代器)得到i的迭代值

  例如以下的代碼:

for i in x:
    print(i)

  完全可以改寫為:

iterator = iter(x)
while True:
    i = next(iterator)
    print(i)

 

從嚴格或者底層原理來說

  迭代器或迭代器對象:實現了__next__()魔法方法的(類所實例化的)對象,該方法返回迭代器下一個值(保存得到下一個迭代值的算法)

  可迭代對象:實現了__iter__()魔法方法的(類所實例化的)對象,該方法返回一個迭代器對象

  

實際上,next和iter是對__next__和__iter__的進一步封裝或者說next和iter在執行的時候又分別調用了內部的__next__和__iter__從而實現迭代器和可迭代對象的特性和功能

 

綜上,我們可以理解for循環、可迭代對象、迭代器三者的聯系:

  for循環只能對可迭代對象進行,可迭代對象又需要迭代器的實現

由此,我們可以自定義實現迭代器和可迭代迭代對象,從而實現自定義的for循環效果 


 

示例:

通過迭代器和可迭代對象實現菲波那切數列

分別定義迭代器和可迭代對象所屬的類:

class Fib:
  '''定義可迭代對象所屬類'''
def __init__(self,num): #num表示該數列的長度   self.a = 1   self.b = 2
     self.current=self.a
     self.num = num def __iter__(self): return FebIterator(self) class FibIterator(self):
  '''定義迭代器類'''
def __init__(self,source): self.source = source def __next__(self):
     
     if(self.num-1>=0):
       self.num = self.num-1     self.current
= self.a     self.a = self.b     self.b = self.b+self.current #以上兩步賦值操作可省略中間變量直接寫為self.a,self.b = self.b,self.a+self,b
       return self.curent
     else: raise StopIteration

通過調用這兩個類的實例化對象,可以實現循環打印斐波那契數列

fib = Fib()
for i in fib: print(i)

實際上,為了簡化和方便,完全可以在一個類中同時實現__iter__()和__next__()方法,也即該類實例化的對象既是一個可迭代對象也是迭代器,代碼如下:

class Fib:
    def __init__():
        self.a = 1
        self.b = 2
     sele.current = self.a def __iter__(self): return self def __next__():
     if(self.num-1>=0):
       self.num = self.num-1     self.current = self.a     self.a = self.b     self.b = self.b+self.current #以上兩步賦值操作可省略中間變量直接寫為self.a,self.b = self.b,self.a+self,b 
       return self.curent
     else: raise StopIteration
 
        

其使用方法和之前沒有區別,反而更加簡便,前提是對迭代器和可迭代對象有清晰的理解和認識,否則會對二者概念產生混淆


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM