>>defspam():yield"first"yield"second"yield"third">>>spam

黄色网页视频 I 影音先锋日日狠狠久久 I 秋霞午夜毛片 I 秋霞一二三区 I 国产成人片无码视频 I 国产 精品 自在自线 I av免费观看网站 I 日本精品久久久久中文字幕5 I 91看视频 I 看全色黄大色黄女片18 I 精品不卡一区 I 亚洲最新精品 I 欧美 激情 在线 I 人妻少妇精品久久 I 国产99视频精品免费专区 I 欧美影院 I 欧美精品在欧美一区二区少妇 I av大片网站 I 国产精品黄色片 I 888久久 I 狠狠干最新 I 看看黄色一级片 I 黄色精品久久 I 三级av在线 I 69色综合 I 国产日韩欧美91 I 亚洲精品偷拍 I 激情小说亚洲图片 I 久久国产视频精品 I 国产综合精品一区二区三区 I 色婷婷国产 I 最新成人av在线 I 国产私拍精品 I 日韩成人影音 I 日日夜夜天天综合

python中的生成器(generator)

系統(tǒng) 2214 0

生成器是python中一個(gè)非常酷的特性,python 2.2中引入后在2.3變成了標(biāo)準(zhǔn)的一部分。它能夠讓你在許多情況下以一種優(yōu)雅而又更低內(nèi)存消耗的方式簡(jiǎn)化無(wú)界(無(wú)限)序列相關(guān)的操作。

生成器是可以當(dāng)做iterator使用的特殊函數(shù),它功能的實(shí)現(xiàn)依賴(lài)于關(guān)鍵字yield,下面是它如何運(yùn)作一個(gè)簡(jiǎn)單的演示:

>>> def spam():
yield " first "
yield " second "
yield " third "


>>> spam
< function spam at 0x011F32B0 >
>>> for x in spam():
print x


first
second
third
>>> gen = spam()
>>> gen
< generator object spam at 0x01220B20 >
>>> gen.next()
' first '
>>> gen.next()
' second '
>>> gen.next()
' third '

在函數(shù)spam()內(nèi)定義了一個(gè)生成器,但是對(duì)spam()的調(diào)用永遠(yuǎn)只能獲得一個(gè)單獨(dú)的生成器對(duì)象,而不是執(zhí)行函數(shù)里面的語(yǔ)句,這個(gè)對(duì)象(generator object)包含了函數(shù)的原始代碼和函數(shù)調(diào)用的狀態(tài),這狀態(tài)包括函數(shù)中變量值以及當(dāng)前的執(zhí)行點(diǎn)——函數(shù)在yield語(yǔ)句處暫停(suspended),返回當(dāng)前的值并儲(chǔ)存函數(shù)的調(diào)用狀態(tài),當(dāng)需要下一個(gè)條目(item)時(shí),可以再次調(diào)用next,從函數(shù)上次停止的狀態(tài)繼續(xù)執(zhí)行,知道下一個(gè)yield語(yǔ)句。

生成器和函數(shù)的主要區(qū)別在于函數(shù) return a value,生成器 yield a value同時(shí)標(biāo)記或記憶 point of the?yield 以便于在下次調(diào)用時(shí)從標(biāo)記點(diǎn)恢復(fù)執(zhí)行。? yield ?使函數(shù)轉(zhuǎn)換成生成器,而生成器反過(guò)來(lái)又返回迭代器。

有三種方式告訴循環(huán)生成器中沒(méi)有更多的內(nèi)容:

  1. 執(zhí)行到函數(shù)的末尾("fall off the end")
  2. 用一個(gè)return語(yǔ)句(它可能不會(huì)返回任何值)
  3. 拋出StopIteration異常

一個(gè) 經(jīng)典的例子 是和C語(yǔ)言中的static語(yǔ)句相比較:在Python沒(méi)有明確支持的所謂static變量,但是在函數(shù)之間相互調(diào)用時(shí),生成器能讓你能以一個(gè)更優(yōu)雅的方式實(shí)現(xiàn)類(lèi)似的效果:

在C語(yǔ)言中 ?fibonacci 函數(shù)的實(shí)現(xiàn):

#include < stdio.h >

int main() {
printf(
" 0\n " );
printf(
" 1\n " );
while ( 1 )
printf(
" %d\n " ,fib());
/* for test use */
// int i=0;
// while(i<20){
// i++;
// printf("%d\n", fib());}
}

int fib() {
static unsigned first = 0 ,second = 1 ,next,retval;

next
= first + second;
retval
= next;
first
= second;
second
= next;

return retval;

}

python實(shí)現(xiàn):

# !/usr/bin/env python
#
-*- coding: utf-8 -*-
#
filename: fib.py

def fib():
first
= 0
second
= 1
yield first
yield second

while 1 :
next
= first + second
yield next
first
= second
second
= next

運(yùn)行:

>>> from fib import fib
>>> fib()
< generator object fib at 0xb76fcfcc >
>>> import itertools
>>> list(itertools.islice(fib(), 10 ))
[0,
1 , 1 , 2 , 3 , 5 , 8 , 13 , 21 , 34 ]

也可以用如下方式截取一部分輸出(但建議使用 itemtools 模塊):

>>> for (i, num) in zip(range( 10 ),fib()):
...
print num

上述 fibonacci 函數(shù)的實(shí)現(xiàn)看起來(lái)較為繁瑣,更加簡(jiǎn)捷優(yōu)雅的實(shí)現(xiàn)如下:

# !/usr/bin/env python
#
-*- coding: utf-8 -*-
#
filename: fib.py

def fib():
first, second
= 0, 1
while 1 :
yield second
first, second
= second, first + second

注意:但是在C語(yǔ)言中由于static的特性,在一個(gè)函數(shù)體內(nèi)當(dāng)需要產(chǎn)生多組 fibonacci 數(shù)列時(shí)可能就需要定義相同的諸如fib1() fib2() fib3()的函數(shù)。python中可以利用上述函數(shù)構(gòu)造任意多個(gè)獨(dú)立的生成器對(duì)象。

至于生成器(generator)應(yīng)該使用在哪些方面以便更好地節(jié)省內(nèi)存——你可以使用在需要計(jì)算列表的值但是每次只需要訪(fǎng)問(wèn)一個(gè)item的地方,和預(yù)先計(jì)算好將其存儲(chǔ)在一個(gè)列表里相比,生成器在運(yùn)行中逐個(gè)計(jì)算其值(computes the values on the fly)。

python中的生成器(generator)


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論