• [TimLinux] Python 迭代器(iterator)和生成器(generator)


    1. 可迭代对象

    from collection import Iterable
    
    
    class Iterable(metaclass=ABCMeta):
        ...
        def __iter__(self):  # 只实现了__iter__ 方法
            while False:
                yield None

    能够在 for ... in obj:中使用的对象(obj)就是一个可迭代对象。

    2. 迭代器

    from collections import Iterator
    
    
    class Iterator(Iterable):  # Iterable的子类
        ...
        def __next__(self):  # 实现了 __next__
            raise StopIteration
    
        def __iter__(self):  # 也实现了 __iter__
            return self

    能够使用.next() 或者 .__next__() 方法,在没有下一个元素时,返回 StopIteration 异常的对象,都是迭代器,可迭代对象转换成迭代器的方法是: iter(obj) 返回的就是一个迭代器。

    >>> a = []
    >>> a
    []
    >>> s = iter(a)
    >>> s
    <list_iterator object at 0x7feac859b048>
    >>> s.next() # 这个方法不存在,抛出的是属性错误异常
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: 'list_iterator' object has no attribute 'next'
    >>> s.__next__
    <method-wrapper '__next__' of list_iterator object at 0x7feac859b048>
    >>> s.__next__()  # 这个方法存在,抛出的是 StopIteration 异常
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    StopIteration
    >>>

    实现自己的迭代器:

    class Reverse:
        def __init__(self, data):
            self.data = data
            self.index = len(data)
    
        def __iter__(self):
            return self
    
        def __next__(self):  # py2: next()方法
            if self.index == 0:
                raise StopIteration
            self.index = self.index - 1
            return self.data[self.index]
    
    rev = Reverse('timlinux')
    for char in rev:
        print(char)

    3. 生成器yield

    生成器(generator)是用来构造迭代器的一种语法工具,通过使用 yield 关键字来代替 return,并自动构建好 __iter__() 和 __next__() 两个方法:

    • yield 关键字的位置将发生 return 操作
    • yield 关键字存在的函数中,将具有 __iter__, __next__ 函数
    def reverse(data):
        max_len = len(data) - 1
        min_len = -1
        for index in range(max_len, min_len, -1):
            yield data[index]
    
    x = reverse('timlinux')
    dir(x)  # py3: 返回的对象有 __iter__, __next__ 方法
            # py2: 返回的对象有 __iter__, next 方法

    列表生成式中的 [] 换成 (),得到的对象就不再是一个列表,而是一个生成器:

    >>> L = [x*x for x in range(10)]
    >>> L
    [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
    >>> g = (x*x for x in range(10))
    >>> g
    <generator object <genexpr> at 0x7f9a8dd48a00>

    4. 场景

    在使用中分配内存,而不是一次分配所有的内存。

  • 相关阅读:
    c++智能指针-shared_ptr
    python全栈学习笔记(二)网络基础之子网划分
    python全栈学习笔记(一)网络基础之网络协议篇
    Fiddler抓包4-工具介绍(request和response)
    python接口自动化5-Json数据处理
    python接口自动化4-绕过验证码登录(cookie) (转载)
    Http status(二)
    python接口自动化1-发送get请求
    Fiddler抓包11-HTTPS证书Actions无法导出问题
    使用idea配置tomcat将web项目跑起来
  • 原文地址:https://www.cnblogs.com/timlinux/p/9700691.html
Copyright © 2020-2023  润新知