ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Python迭代器

2022-07-09 23:31:38  阅读:181  来源: 互联网

标签:__ 迭代 Python self iter next v2


最近在看Python基础教程(第三版),是之前python课的课本,但是之前没读过,虽然python一直用得挺多,但重新读读收获还挺大。这里做个笔记。
先是迭代器是什么并简单实现一个迭代器,然后是实现了一些range()。


​ 迭代器是像循环一样重复很多次,但不会像列表那样一次性全部生成,而是需要用的时候再生成,就节省了内存资源。有时可能只想一个个地获取值,而不是用列表一次性获取,列表可能占用太多内存,并且有时没办法使用列表,列表的长度会到无穷大。


1、根据基本定义实现一个迭代器类

简单的说,迭代器类中:

  • 定义__iter__和__next__两个方法
  • __iter__返回它自己,__next__返回下一个,没有可返回的就抛出StopIteration异常。
  • 迭代器对象Iterator就是字面意思,可以被迭代,比如可以调用next方法(一个迭代器对象it,next(it)就是it.__next__() ),比如可以放进for循环(for x in it)

根据上面描述可以简单写一个迭代器出来

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))

运行的结果是:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]


2、稍微具体一点的__iter__和__next__

嗯于是就能知道了,关于__iter__和__next__:

实现了方法__iter__的对象是可迭代的,而实现了方法__next__的对象是迭代器。

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

文档中也写得很清楚了,调用__next__时,迭代器应返回其下一个值。如果迭代器没有可供返回的值,则引发StopIteration异常。

iter返回一个迭代器对象,即object.__iter__()。如果指定了sentinel(哨兵),这个迭代器将不断调用直到返回的是sentinel。


3、for循环的原理,斐波那契数列的例子

然后再来一个斐波那契数列的例子,迭代器对象可以被放进for循环。

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:  # 首先会执行__iter__方法获取返回值,就它自己,然后执行一次它的__next__方法,不断循环。
        if f > 1000:
            print(f)
            break

返回这个数列中第一个大于1000的数,是1597。


4、关于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就是执行v1的__iter__获取到里面的迭代器对象v2,再执行v2的__next__方法...

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

于是实现一下range就很简单了,在实现的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打印出来。

标签:__,迭代,Python,self,iter,next,v2
来源: https://www.cnblogs.com/eisenji/p/16462245.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有