欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

解析Python中的生成器及其與迭代器的差異

 更新時間:2016年06月20日 16:58:54   作者:catHeart  
生成器是一種特殊的迭代器,而反過來說則就不對了,迭代器在Python中是一個更抽象的概念,以下我們就來詳細解析Python中的生成器及其與迭代器的差異

生成器
生成器是一種迭代器,是一種特殊的函數(shù),使用yield操作將函數(shù)構(gòu)造成迭代器。普通的函數(shù)有一個入口,有一個返回值;當函數(shù)被調(diào)用時,從入口開始執(zhí)行,結(jié)束時返回相應(yīng)的返回值。生成器定義的函數(shù),有多個入口和多個返回值;對生成器執(zhí)行next()操作,進行生成器的入口開始執(zhí)行代碼,yield操作向調(diào)用者返回一個值,并將函數(shù)掛起;掛起時,函數(shù)執(zhí)行的環(huán)境和參數(shù)被保存下來;對生成器執(zhí)行另一個next()操作時,參數(shù)從掛起狀態(tài)被重新調(diào)用,進入上次掛起的執(zhí)行環(huán)境繼續(xù)下面的操作,到下一個yield操作時重復上面的過程。Python的循環(huán)操作與C語言的實現(xiàn)不同,如果使用List等數(shù)據(jù)結(jié)構(gòu)需要耗費大量的內(nèi)容;循環(huán)操作中使用生成器只需要在內(nèi)存中實例化一個對象,可以減少內(nèi)存占用,提高循環(huán)操作的執(zhí)行速度。

>>>def myG():
...  yield 1
...  yield 2
...  yield 3
...
>>>g=myG()
>>>next(g)
1
>>>next(g)
2
>>>next(g)
3
>>>next(g)
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
StopIteration
>>>g2=myG()
>>>for i in g2:
...  print(i)
1
2
3

生成器表達式
for...[if]...語句可以簡潔的構(gòu)建一個List,同時也可以用來構(gòu)建生成器。

>>>a=[7,8,9]
>>>b=[i**2 for i in a]
>>>b
[49, 64, 81]
>>>ib=(i**2 for i in a)
>>>ib
<generator object <genexpr> at 0x7f72291217e0>
>>>next(ib)
49
>>>next(ib)
64
>>>next(ib)
81
>>>next(ib)
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
StopIteration

迭代器(Iterator)與生成器(Generator)的區(qū)別
迭代器是一個更抽象的概念,任何對象,如果它的類有next方法(next python3)和iter方法返回自己本身。

每個生成器都是一個迭代器,但是反過來不行。通常生成器是通過調(diào)用一個或多個yield表達式構(gòu)成的函數(shù)s生成的。同時滿足迭代器的定義。

當你需要一個類除了有生成器的特性之外還要有一些自定義的方法時,可以使用自定義的迭代器,一般來說生成器更方便,更簡單。

def squares(start, stop):
  for i in xrange(start, stop):
    yield i*i

等同于生成器表達式:

(i*i for i in xrange(start, stop))

列表推倒式是:

[i*i for i in xrange(start, stop)]

如果是構(gòu)建一個自定義的迭代器:

class Squares(object):
  def __init__(self, start, stop):
    self.start = start
    self.stop = stop
  def __iter__(self):
    return self
  def next(self):
    if self.start >= self.stop:
      raise StopIteration
    current = self.start * self.start
    self.start += 1
    return current

此時,你還可以定義自己的方法如:

def current(self):
  return self.start

兩者的相同點:對象迭代完后就不能重寫迭代了。

相關(guān)文章

最新評論