python讓實例作用於for循環並當做list來使用


python如果想讓一個類被用於for....in  循環,類型list和tuple那樣,可以實現__iter__方法。

這個方法返回一個迭代對象,python的for循環就會不斷調用該迭代對象的next()方法拿到循環的下一個值,直到遇到StopIteration錯誤時退出循環。

class  Fib(object):
    def  __init__(self):
        self.a,self.b=0,1   #初始化兩個計數器a,b
    def   __iter__(self):
        return self  #實例本身就是迭代對象,故返回自己
    def  next(self):
        self.a,self.b=self.b,self.a+self.b   #計算下一個值
        if  self.a>100000:    #退出循環的條件
            raise  StopIteration()
        return self.a
    

 把Fib實例作用於for循環:

for  n  in  Fib():
    print  n   
    
    
1
1
2
3
5
...
46368
75025

 Fib 實例雖然能作用於for循環,看起來和list有點像,但是,把它當成list來使用還是不行,例如,按下標取元素

print  Fib()[5]
此時會報錯:TypeError: 'Fib' object does not support indexing

要實現按下標取元素,需要實現__getitem__()方法

   def  __getitem__(self,n):
        a,b=1,1
        for x  in range(n):
            a,b=b,a+b
        return  a

 按下標獲取元素

f=Fib()
print  f[0]   #1
print  f[1]   #1
print  f[10]   #89
print f[100]   #573147844013817084101

 list 有個切片方法獲取元素

print  range(100)[5:10]     #[5, 6, 7, 8, 9]

 對於Fib卻報錯,原因是__getitem__傳入的參數可能是一個int,也可能是一個切片對象slice,需要做判斷

def __getitem__(self, n):
        if isinstance(n, int):
            a, b = 1, 1
            for x in range(n):
                a, b = b, a + b
            return a
        if isinstance(n, slice):
            start = n.start
            stop = n.stop
            a, b = 1, 1
            L = []
            for x in range(stop):
                if x >= start:
                    L.append(a)
                a, b = b, a + b
            return L

  試試Fib的切片

f=Fib()
print f[0:5]     #==>[1, 1, 2, 3, 5]

print f[:10]  # ==>[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

 


免責聲明!

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



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