欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

Python迭代器和生成器

系統(tǒng) 1969 0

· 迭代器

什么是迭代器:
迭代器可以讓我們?cè)L問集合的時(shí)候變得非常方便。之前我們通過for…in…來(lái)訪問一個(gè)集合的時(shí)候,就是使用迭代器完成的。
如果沒有迭代器,那么我們只能通過while循環(huán),每次循環(huán)的時(shí)候通過下標(biāo)來(lái)訪問了。
可迭代對(duì)象:
可以直接使用for循環(huán)遍歷的對(duì)象,成為可迭代的對(duì)象,常見的可迭代對(duì)象有:list、tuple、dict、set、str以及生成器
更加專業(yè)的判斷一個(gè)對(duì)象是否是可迭代對(duì)象:這個(gè)對(duì)象有一個(gè)__iter__方法,并且這個(gè)方法會(huì)返回一個(gè)迭代器對(duì)象,這種對(duì)象就叫做可迭代對(duì)象。
判斷一個(gè)對(duì)象是否可迭代:
可以使用is instance()判斷一個(gè)對(duì)象是否是interable對(duì)象

            
              from collections import Iterable

# 列表是一個(gè)可迭代對(duì)象
ret = isinstance([1, 2, 3], Iterable)
print(ret)

            
          

字符串是一個(gè)可迭代對(duì)象

            
              ret = isinstance('abc', Iterable)
print(ret)

            
          

整形不是一個(gè)可迭代對(duì)象

            
              ret = isinstance(123, Iterable)
print(ret)

            
          

迭代器:
1、在python2中,實(shí)現(xiàn)了next和__iter__方法,并且在這個(gè)方法中返回了值的對(duì)象,叫做迭代器對(duì)象
2、在python3中,實(shí)現(xiàn)了__next__方法和__iter__方法,并且在這個(gè)方法中返回了值的對(duì)象,叫做迭代器對(duì)象
3、如果迭代器沒有返回值了,那么應(yīng)該在next或者是__next__方法中拋出一個(gè)StopInteration
使用iter()方法獲取可迭代對(duì)象的迭代器:
有時(shí)候我們擁有了一個(gè)可迭代的對(duì)象,我們想要獲取這個(gè)迭代器,那么可以通過iter(x)方法獲取這個(gè)可迭代對(duì)象
的迭代器。
自定義迭代器:

分開的寫法(方法A):

            
              class MyRangeIterator:
    """
    迭代器
    """
    def __init__(self, start, end):
        self.index = start
        self.end = end

    def __iter__(self):
        return self

    def __next__(self):
        if self.index < self.end:
            temp = self.index
            self.index += 1
            return temp
        else:
            raise StopIteration()


class MyRange:
    """
    MyRange是可迭代對(duì)象
    """
    def __init__(self, start, end):
        self.start = start
        self.end = end

    def __iter__(self):
        # 這個(gè)方法中返回一個(gè)迭代器對(duì)象
        return MyRangeIterator(self.start, self.end)


if __name__ == '__main__':
    myrange = MyRange(1, 10)
    for i in myrange:
        print(i)

    iterator = iter(myrange)
    while True:
        try:
            x = iterator.__next__()
            print(x)
        except StopIteration:
            break

            
          

合并到一起的寫法(方法B):

            
              # -*- coding: UTF-8 -*-

from collections import Iterable, Iterator

# Interable: 判斷是否可迭代
# Interator: 判斷是否是迭代器

print(isinstance('abc', Iterable))
print(isinstance('abc', Iterator))

class MyRange:

    def __init__(self, start, end):
        self.index = start
        self.end = end

    def __iter__(self):
        # 這個(gè)方法要返回一個(gè)迭代器
        return self

    def __next__(self):
        if self.index < self.end:
            temp = self.index
            self.index += 1
            return temp
        else:
            raise StopIteration()

if __name__ == '__main__':
    myrange = MyRange(1, 10)
    for i in myrange:
        print(i)
    for i in myrange:
        print(i)

            
          

以上兩個(gè)方法,A和B都實(shí)現(xiàn)了迭代器的功能,當(dāng)我們實(shí)例化MyRange時(shí),即獲得了一個(gè)可迭代對(duì)象,在方法A中這個(gè)可迭代對(duì)象返回了一個(gè)迭代器:MyRangeIterator(self.start, self.end),方法B中返回了自己self本身。這時(shí)就會(huì)有一個(gè)區(qū)別產(chǎn)生,因?yàn)锳方法在每次返回迭代器的時(shí)候,都會(huì)實(shí)例化迭代
器,而B中只會(huì)實(shí)例化一次,因此:

            
              myrange = MyRange(1, 10)
for i in myrange:
    print(i)
for i in myrange:
    print(i)

            
          

如果兩個(gè)方法都執(zhí)行上述代碼,A方法每次都會(huì)遍歷出1到9,而B方法只會(huì)遍歷一次,第二次什么都不會(huì)打印。因?yàn)榈诙蝧elf.index 已經(jīng)等于了 self.end。

· 生成器
為什么需要生成器:
當(dāng)我們需要打印一個(gè)1到1億的整形的時(shí)候,如果我們采用普通的方式,直接調(diào)用range函數(shù),程序會(huì)崩潰掉。因?yàn)閞ange(1,100000000)函數(shù)會(huì)直接產(chǎn)生一個(gè)從1-1億的列表,這個(gè)列表中所有數(shù)據(jù)都是存放在內(nèi)存中的,會(huì)導(dǎo)致內(nèi)存爆滿。這時(shí)候我們可以采用生成器來(lái)解決該問題,生成器不會(huì)一次把所有數(shù)據(jù)都加載到內(nèi)存中,而是在循環(huán)的時(shí)候臨時(shí)產(chǎn)生的,循環(huán)一次生成一個(gè),所以程序在運(yùn)行期間永遠(yuǎn)都只會(huì)生成一個(gè)數(shù)據(jù),從而節(jié)省內(nèi)存的開銷。
next函數(shù)和__next__方法:
next函數(shù)可以迭代生成器的返回值
自己寫生成器:
生成器可以通過函數(shù)產(chǎn)生。如果在一個(gè)函數(shù)中出現(xiàn)了yield表達(dá)式,那么這個(gè)函數(shù)將不再是一個(gè)普通的函數(shù),而是一個(gè)生成器函數(shù)。yield一次返回一個(gè)結(jié)果,并且會(huì)凍結(jié)當(dāng)前函數(shù)的狀態(tài)。

普通的列表

num_list = [x for x in range(1, 100)]
print(num_list)

生成式

num_gen = (x for x in range(1, 100))
print(num_gen)
print(type(num_gen))

for i in num_gen:

print(i)

def my_gen():
yield 1
yield 2
yield 3

ret = my_gen()
print(next(ret))
print(next(ret))
print(next(ret))

print(next(ret))

def gen(start, end):
index = start
while index <= end:
yield index
index += 1

生成器有兩個(gè)身份:迭代器和可迭代的對(duì)象, 因此,只能被遍歷一次

ret = gen(1, 100000000)
for i in ret:
print(i)
send方法:
1、也是用來(lái)觸發(fā)代碼,直接碰到y(tǒng)ield表達(dá)式
2、如果用send方法執(zhí)行剛剛開始的生成器,那么應(yīng)該傳遞None給send方法
def my_gen(start):
while start < 10:
# 如果通過next函數(shù)執(zhí)行yield
# 那么yield xxx 永遠(yuǎn)都是返回None
temp = yield start
print(temp)
start += 1

ret = my_gen(1)

第一次使用send方法必須傳None

print(ret.send(None))
print(next(ret))
print(ret.send(‘hello’))

1

None

2

hello

3

send方法和next函數(shù)的區(qū)別:
1、send方法可以傳遞值給yield表達(dá)式,而next不可以
2、在第一次執(zhí)行生成器代碼的時(shí)候,必須要傳None,next則不需要
生成器的一些案例:

            
              def fib(count):
    index = 1
    a, b = 0, 1
    while index <= count:
        yield b
        c = b
        b = a + b
        a = c
        index +=1
for x in fib(7):
    print(x)

#使用生成器 來(lái)實(shí)現(xiàn)多線程,聽音樂和看電影同時(shí)進(jìn)行
def netease_music(duration):
    time = 0
    while time <= duration:
        print('音樂聽了%d分鐘' % time)
        time += 1
        yield None
    # raise StopIteration()

def youku_movie(duration):
    time = 0
    while time <= duration:
        print('電影看了%d分鐘' % time)
        time += 1
        yield None
    # raise StopIteration()


if __name__ == '__main__':
    music_iter = netease_music(10)
    movie_iter = youku_movie(30)
    music_stop = False
    movie_stop = False
    while True:
        try:
            next(music_iter)
        except StopIteration:
            print('音樂聽完了')
            music_stop = True
        try:
            next(movie_iter)
        except StopIteration:
            print('電影看完了')
            movie_stop = True
        if music_stop and movie_stop:
            break

            
          

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

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

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

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

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

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

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 日本无卡码免费一区二区三区 | 久久人人爽人人爽人人 | 国产视频在线免费观看 | 亚洲视频在线视频 | 欧美日韩免费播放一区二区 | 污视频免费观看网站 | 欧美亚洲另类视频 | 99只有精品 | 成人av一区二区三区 | 国产羞羞视频免费在线观看 | 色五月视频 | 免费视频一区二区 | 精品一卡2卡三卡4卡免费视频 | 99精品欧美一区二区三区 | 亚洲人与黑人xxxx | 精品久久一区二区 | 色多多成视频人在线观看 | 在线观看欧美成人 | 99久久这里只有精品 | 色黄视频在线观看 | 国产亚洲精品一区二区 | 欧美成人免费在线视频 | 一级毛片免费视频 | 自拍偷拍亚洲视频 | 色综合精品久久久久久久 | 成人免费黄色网 | 九色视频网址 | 一个人看aaaa免费中文 | 很黄很粗很湿很刺激的视频 | 亚洲精品一区二区三区四区高清 | 欧美精品国产一区二区三区 | 国产精品最新 | 91精品亚洲 | 综合色视频 | 亚洲第一视频 | 一级毛片免费在线播放 | 天天碰人人 | 久热免费在线视频 | 手机在线一区二区三区 | 欧美国产激情二区三区 | 日韩黄色一级视频 |