日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
創(chuàng)新互聯(lián)Python教程:一篇文章教你如何使用Python生成器

自從 PEP 255 引入生成器以來(lái),它就是 Python 中重要的一部分.

創(chuàng)新互聯(lián)成立與2013年,先為龍山等服務(wù)建站,龍山等地企業(yè),進(jìn)行企業(yè)商務(wù)咨詢服務(wù)。為龍山企業(yè)網(wǎng)站制作PC+手機(jī)+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問(wèn)題。

生成器允許你定義一個(gè)有迭代器行為的函數(shù).

它允許程序猿更快,更簡(jiǎn)單并且以一個(gè)干凈的方式創(chuàng)建一個(gè)迭代器.

那么什么是迭代器呢,你或許會(huì)問(wèn)?

 iterator 迭代器是一個(gè)可以被迭代的(循環(huán))對(duì)象。它可以抽象為一個(gè)裝著數(shù)據(jù)同時(shí)有著可迭代對(duì)象的行為的容器?;蛟S你已經(jīng)每天在使用一些可迭代的對(duì)象:諸如字符串,列表,字典或其它名字的對(duì)象.

一個(gè)迭代器是一個(gè)實(shí)現(xiàn)了迭代器接口 Iterator Protocol 的類。這個(gè)接口為類提供了兩個(gè)方法: __iter__ 和 __next__.

嗯~回到上一步。你為什么想要?jiǎng)?chuàng)建一個(gè)迭代器呢?

節(jié)省內(nèi)存空間

當(dāng)實(shí)例化后,迭代器并不會(huì)計(jì)算它每一個(gè)項(xiàng)的值,他們只會(huì)等你訪問(wèn)這些項(xiàng)的時(shí)候采取計(jì)算。這也就是眾所周知的惰性求值。

當(dāng)你有一個(gè)非常大的數(shù)據(jù)集需要計(jì)算時(shí),惰性求值是很有用處的。它允許你馬上就能開始使用數(shù)據(jù),盡管整個(gè)數(shù)據(jù)集還在計(jì)算中。

假設(shè)我們想要獲得小于某個(gè)值的所有素?cái)?shù)。

我們先定義一個(gè)函數(shù),它可以檢查一個(gè)數(shù)字是否為素?cái)?shù):

def check_prime(number):
    for divisor in range(2, int(number ** 0.5) + 1):
        if number % divisor == 0:
            return False
    return True

然后,我們定義一個(gè)迭代器類,包含__iter__ 和 __next__ 方法。

class Primes:
    def __init__(self, max):
        self.max = max
        self.number = 1
    def __iter__(self):
        return self
    def __next__(self):
        self.number += 1
        if self.number >= self.max:
            raise StopIteration
        elif check_prime(self.number):
            return self.number
        else:
            return self.__next__()

Primes 類通過(guò)給定一個(gè)值來(lái)實(shí)例化。如果下一個(gè)素?cái)?shù)比值 max 還要大,迭代器就會(huì)拋出一個(gè) StopIteration 異常來(lái)把迭代器停掉。

當(dāng)我們請(qǐng)求迭代器中的下一個(gè)元素時(shí),它會(huì)給 number 加 1 并檢查這個(gè)數(shù)字是否為素?cái)?shù)。如果不是,它會(huì)再次調(diào)用__next__直到 number 成為素?cái)?shù)。一旦如此,迭代器就將這個(gè)數(shù)字返回。

通過(guò)使用迭代器,我們并不會(huì)在內(nèi)存中創(chuàng)建一個(gè)包含很多素?cái)?shù)的列表。相反,我們將會(huì)在每次請(qǐng)求下一個(gè)素?cái)?shù)時(shí)才去生成它。

讓我們來(lái)試一試:

primes = Primes(100000000000)
print(primes)
for x in primes:
    print(x)
    ......
<__main__.Primes object at 0x1021834a8>
2
3
5
7
11
...

對(duì) Primes 對(duì)象的每一次迭代都調(diào)用了 __next__ 來(lái)生成下一個(gè)素?cái)?shù)。

迭代器只可以被迭代一輪。如果你嘗試再迭代 primes 一輪,它將不會(huì)返回任何值,表現(xiàn)得就像個(gè)空列表。

既然我們已經(jīng)知道了什么是迭代器,以及怎么制作一個(gè)迭代器,我們接下來(lái)將繼續(xù)來(lái)看看生成器。

生成器

回想下,生成器函數(shù)允許我們以一種更簡(jiǎn)單的方式來(lái)創(chuàng)建迭代器。

生成器給 Python 引入了 yield 聲明。它用起來(lái)有點(diǎn)像 return,因?yàn)樗鼤?huì)返回一個(gè)值。

區(qū)別在于 yield 會(huì)保存函數(shù)的狀態(tài)。在函數(shù)下一次被調(diào)用時(shí),將會(huì)從其離開的地方繼續(xù)執(zhí)行,并且變量值也與它之前執(zhí)行 yield 操作前相同。

如果把我們的 Primes 迭代器轉(zhuǎn)換為生成器,它看起來(lái)會(huì)像這樣:

def Primes(max):
    number = 1
    while number < max:
        number += 1
        if check_prime(number):
            yield number
primes = Primes(100000000000)
print(primes)
for x in primes:
    print(x)
......

2
3
5
7
11

現(xiàn)在真是太 pythonic 了!我們還能再給力點(diǎn)嗎?

當(dāng)然!我們可以使用 PEP 289 中介紹的生成器表達(dá)式。

這相當(dāng)于是生成器的列表推導(dǎo)式。它用起來(lái)與列表推導(dǎo)式相同,不過(guò)表達(dá)式由 () 包裹而不是 []。

下面的表達(dá)式可以代替我們上面的生成器函數(shù):

primes = (i for i in range(2, 100000000000) if check_prime(i))
print(primes)
for x in primes:
    print(x)
......
 at 0x101868e08>
2
3
5
7
11
...

這就是 Python 生成器的美妙之處。

總結(jié)

生成器允許你以一種非常 pythonic 的方式來(lái)創(chuàng)建迭代器。迭代器允許惰性求值,只有在請(qǐng)求下一個(gè)元素時(shí)迭代器對(duì)象才會(huì)去生成它。這對(duì)于非常大的數(shù)據(jù)集是很有用的。迭代器和生成器都只能被迭代一輪。生成器函數(shù)比迭代器更好。生成器表達(dá)式比迭代器更好(只在簡(jiǎn)單情況下如此)。


文章名稱:創(chuàng)新互聯(lián)Python教程:一篇文章教你如何使用Python生成器
文章網(wǎng)址:http://m.5511xx.com/article/ccdsoio.html