真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Python迭代器

最近在看Python基礎(chǔ)教程(第三版),是之前python課的課本,但是之前沒讀過,雖然python一直用得挺多,但重新讀讀收獲還挺大。這里做個筆記。
先是迭代器是什么并簡單實現(xiàn)一個迭代器,然后是實現(xiàn)了一些range()。后面本來想寫生成器和八皇后問題,但是發(fā)現(xiàn)了一些很不錯的博客,比我能寫出來的好多了,把鏈接收藏在后面了。

創(chuàng)新互聯(lián)專注于企業(yè)營銷型網(wǎng)站、網(wǎng)站重做改版、十堰鄖陽網(wǎng)站定制設(shè)計、自適應(yīng)品牌網(wǎng)站建設(shè)、H5建站成都做商城網(wǎng)站、集團公司官網(wǎng)建設(shè)、成都外貿(mào)網(wǎng)站制作、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁設(shè)計等建站業(yè)務(wù),價格優(yōu)惠性價比高,為十堰鄖陽等各大城市提供網(wǎng)站開發(fā)制作服務(wù)。


? 迭代器是像循環(huán)一樣重復(fù)很多次,但不會像列表那樣一次性全部生成,而是需要用的時候再生成,就節(jié)省了內(nèi)存資源。有時可能只想一個個地獲取值,而不是用列表一次性獲取,列表可能占用太多內(nèi)存,并且有時沒辦法使用列表,列表的長度會到無窮大。


1、根據(jù)基本定義實現(xiàn)一個迭代器類

簡單的說,迭代器類中:

  • 定義__iter__和__next__兩個方法
  • __iter__返回它自己,__next__返回下一個,沒有可返回的就拋出StopIteration異常。
  • 迭代器對象Iterator就是字面意思,可以被迭代,比如可以調(diào)用next方法(一個迭代器對象it,next(it)就是it.__next__() ),比如可以放進for循環(huán)(for x in it)

根據(jù)上面描述可以簡單寫一個迭代器出來

class TestIterator:
    value = 0

    def __next__(self):  
        self.value += 1
        if self.value > 10:  # 到這個條件了沒有可返回的了就拋出一個StopIteration異常
            raise StopIteration
        return self.value  # 每次返回下一個
    
    def __iter__(self):  # 這里返回它自己
        return self


if __name__ == '__main__':
    ti = TestIterator()
    print(list(ti))

運行的結(jié)果是:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]


2、稍微具體一點的__iter__和__next__

嗯于是就能知道了,關(guān)于__iter__和__next__:

實現(xiàn)了方法__iter__的對象是可迭代的,而實現(xiàn)了方法__next__的對象是迭代器。

方法__iter__返回一個迭代器,它是包含方法__next__的對象。

文檔中也寫得很清楚了,調(diào)用__next__時,迭代器應(yīng)返回其下一個值。如果迭代器沒有可供返回的值,則引發(fā)StopIteration異常。

iter返回一個迭代器對象,即object.__iter__()。如果指定了sentinel(哨兵),這個迭代器將不斷調(diào)用直到返回的是sentinel。


3、for循環(huán)的原理,斐波那契數(shù)列的例子

然后再來一個斐波那契數(shù)列的例子,迭代器對象可以被放進for循環(huán)。

class Fibs:
    def __init__(self) -> None:
        self.a = 0
        self.b = 1

    def __next__(self):
        self.a, self.b = self.b, self.a + self.b
        return self.a
    
    def __iter__(self):
        return self


if __name__ == '__main__':
    fibs = Fibs()
    for f in fibs:  # 首先會執(zhí)行__iter__方法獲取返回值,就它自己,然后執(zhí)行一次它的__next__方法,不斷循環(huán)。
        if f > 1000:
            print(f)
            break

返回這個數(shù)列中第一個大于1000的數(shù),是1597。


4、關(guān)于range()

(base) eisen@pop-os:~$ python3.8
Python 3.8.10 (default, Mar 15 2022, 12:22:08) 
[GCC 9.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> v1 = range(20)
>>> dir(v1)
['__bool__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'count', 'index', 'start', 'step', 'stop']

這里先看到v1里面只有__iter__,v1為可迭代對象Iterable,讓v2 = v1.__iter__()

>>> v2 = v1.__iter__()
>>> dir(v2)
['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__length_hint__', '__lt__', '__ne__', '__new__', '__next__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__']

可以看到v2既有__iter__又有__next__為迭代器對象。range就是執(zhí)行v1的__iter__獲取到里面的迭代器對象v2,再執(zhí)行v2的__next__方法...

>>> v2.__next__()
0
>>> v2.__next__()
1
>>> v2.__next__()
2
>>> v2.__next__()
3
>>> v2.__next__()
4
>>> v2.__next__()
5

到這里就能理解書上這段話了。

于是實現(xiàn)一下range就很簡單了,在實現(xiàn)的MyRange里面,__iter__方法就生成一個IterRange類的迭代器對象。

class IterRange():
    def __init__(self, num):
        self.num = num
        self.counter = -1

    def __iter__(self):
        return self

    def __next__(self):
        self.counter += 1
        if self.counter == self.num:
            raise StopIteration()
        return self.counter


class MyRange():
    def __init__(self, num):
        self.num = num

    def __iter__(self):
        return IterRange(self.num)


v1 = MyRange(20)
for i in v1:
    print(i)

輸出就是把0到19打印出來。


本來還想寫后面的生成器和八皇后問題,但是發(fā)現(xiàn)了一些很不錯的博客,我就沒必要自己寫了。這里收藏一下。

Python中生成器的原理,這一篇講了生成器的使用方法,和詳細的原理(里面有源碼)

深入理解Python中的生成器,這一篇寫了生成器的語法,以及它支持的方法close/send等。

python生成器和迭代器有這篇就夠了,這篇寫得很詳細,后面還有補充itertools庫的學(xué)習(xí)。

還記得八皇后的解法嗎,這篇講了個故事。


網(wǎng)頁名稱:Python迭代器
鏈接URL:http://weahome.cn/article/dsoggii.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部