python模塊學習:Iterators和Generators

轉自:http://www.cnblogs.com/zhbzz2007/p/6102695.htmlhtml

1 迭代器:python

迭代器,容許你在一個容器上進行迭代的對象。函數

python的迭代器主要是經過__iter__和__next__兩個方法來實現。spa

__iter__,要求你的容器支持迭代,返回對象自己。若是想建立一個迭代器對象,還須要實現__next__方法,這個返回下一個對象。code

爲了對這些概念更加清晰,讓咱們回顧下面的兩個定義:htm

  • 可迭代對象(iterable),只定義了__iter__方法;
  • 迭代器(iterator),定義了__iter__和__next__兩個方法,__iter__返回迭代器自己,__next__方法返回下一個元素

全部函數名中有雙下劃線的方法,都很神奇,你不須要直接調用__iter__或者__next__。你可使用for循環或者轉換爲列表,Python就會自動替你調用這些方法。固然你或許仍是想調用它們,那麼你可使用Python內置的函數iter和next方法。對象

python3中,list是支持迭代的,但不是迭代器對象。由於,它不支持__next__blog

看代碼:generator

a=[1,2,3,4,5]
next(a)

錯誤信息是:it

C:\Python35\python.exe C:/Users/wcf/PycharmProjects/Algorithms/wcf.py
Traceback (most recent call last):
  File "C:/Users/wcf/PycharmProjects/Algorithms/wcf.py", line 3, in <module>
    next(a)
TypeError: 'list' object is not an iterator

Process finished with exit code 1

經過iter內建函數,能夠把他轉變成迭代器:

a=[1,2,3,4,5]

for item in iter(a):
    print(item)

當你使用循環來遍歷一個迭代器,你就不須要調用next方法,你也無需擔憂會收到StopIteration異常信息。

好比:

a=[1,2,3,4,5]

a_iter=iter(a)
next(a_iter)
next(a_iter)
next(a_iter)
next(a_iter)
next(a_iter)
next(a_iter)
next(a_iter)

會出錯的:

C:\Python35\python.exe C:/Users/wcf/PycharmProjects/Algorithms/wcf.py
Traceback (most recent call last):
  File "C:/Users/wcf/PycharmProjects/Algorithms/wcf.py", line 10, in <module>
    next(a_iter)
StopIteration

Process finished with exit code 1

 

2.建立屬於本身的迭代器,很簡單,實現幾個方法就能夠:

class my_iterator():
    def __init__(self,letters):
        self.letters=letters
        self.position=0

    def __iter__(self):
        return self

    def __next__(self):
        if self.position>=len(self.letters):
            raise StopIteration
        letter=self.letters[self.position]
        self.position+=1
        return letter

if __name__=="__main__":
    i=my_iterator('abcd')
    for item in i:
        print(item)

 

3.生成器

一個普通的Python函數常常返回一個值,不管它是列表、整數仍是其餘對象。可是若是你想調用一個函數,這個函數可否產生一系列值呢?這個就是生成器誕生的緣由。生成器的工做機制是保存它所中止(或者說它已經產生)的位置,而後給主調函數返回一個值。不是返回一個調用函數的執行,生成器僅僅返回一個臨時的控制返回。爲了完成這個功能,生成器函數須要使用Python的 yield 語句。

def double_generator():
    number=2
    while True:
        yield number
        number+=2


doubler =double_generator()

print(next(doubler))
print(next(doubler))
print(next(doubler))
print(next(doubler))

輸出是:

C:\Python35\python.exe C:/Users/wcf/PycharmProjects/Algorithms/wcf.py
2
4
6
8

Process finished with exit code 0

實際上,上文,也有一個next方法。

而下面的例子,就是沒有:

def double_generator():
        yield 'wcf1'
        yield 'wcf2'
        yield 'wcf3'


doubler =double_generator()

print(next(doubler))
print(next(doubler))
print(next(doubler))

輸出是:

C:\Python35\python.exe C:/Users/wcf/PycharmProjects/Algorithms/wcf.py
wcf1
wcf2
wcf3

Process finished with exit code 0

一樣的,若是是:

def double_generator():
        yield 'wcf1'
        yield 'wcf2'
        yield 'wcf3'


doubler =double_generator()

print(next(doubler))
print(next(doubler))
print(next(doubler))
print(next(doubler))

同樣會觸發一場:

C:\Python35\python.exe C:/Users/wcf/PycharmProjects/Algorithms/wcf.py
wcf1
Traceback (most recent call last):
wcf2
wcf3
  File "C:/Users/wcf/PycharmProjects/Algorithms/wcf.py", line 12, in <module>
    print(next(doubler))
StopIteration

Process finished with exit code 1

而這樣寫,就ok:

def double_generator():
        yield 'wcf1'
        yield 'wcf2'
        yield 'wcf3'


doubler =double_generator()

for item in doubler:
    print(item)
相關文章
相關標籤/搜索