python:迭代器类型

Python 对于容器类型数据支持逐个进行迭代处理,迭代会对所有元素按照一个逻辑进行计算操作。因此在 Python 所有数据范围内就存在类型是否是可迭代的话题。

  • 为了高效完成迭代操作, python专门设计了迭代器类型, 这类数据专门用来迭代操作
  • 为了高效快捷创建一个迭代器类型,Python 又有一个生成器类型成生成一个可迭代对象。

迭代器类型

迭代器(iterator)就是一个封装了迭代的对象。Python中内置的序列,如list、tuple、str、bytes、dict、set、collections.deque 等都是可迭代对象,但它们不是迭代器。迭代器可以被 next() 函数调用,并不断返回下一个值。Python 从可迭代的对象中获取迭代器。

迭代器和生成器都是为了惰性求值(lazy evaluation),避免浪费内存空间,实现高效处理大量数据。

  • 在 Python 3中,生成器有广泛的用途,所有生成器都是迭代器,因为生成器完全实现了迭代器接口。
  • 迭代器用于从集合中取出元素
  • 生成器用于"凭空"生成元素 。

迭代器用于支持:

  • for 循环
  • 构建和扩展集合类型
  • 逐行遍历文本文件
  • 列表推导、字典推导和集合推导
  • 元组拆包
  • 调用函数时,使用 * 拆包实参

判断对象是否为迭代器:

from collections import abc

isinstance([1,2,3], abc.Iterator)
# False

isinstance((1,2,3), abc.Iterator)
# False

isinstance({'name': 'lily', 'age': 18}, abc.Iterator)
# False

isinstance({1, 2, 3}, abc.Iterator)
# False

isinstance('abc', abc.Iterator)
# False

isinstance(123, abc.Iterator)
# False

# 生成器表达式,见下文
isinstance((x*2 for x in range(5)), abc.Iterator)
# True

可以看到,常见的类型,它们不是迭代器类型.

那, 如何让一个对象成为迭代器类型呢?

  • 要转为迭代器类型可以用内置函数 iter(),要使用 内置函数 iter() 需要对此对象支持此函数。
  • 对于容器类型,需要实现 container.__iter__ () 方法来提供可扩展的支持,用来支持使用内置函数 iter() 将其转为 迭代器类型,Python 大多内置的容器已经实现了这个方法。
from collections import abc

it = iter('abc')
it
# <str_iterator at 0x7f8482595e70>

isinstance(it, abc.Iterator)
# True
  • 对于其他类型对象,从技术上讲, python迭代器对象必须支持迭代器协议。所谓迭代器协议,就是要求一个迭代器必须要实现如下两个方法:
    • iterator.__iter__():返回迭代器对象本身
    • iterator.__next__():从容器中返回下一个项
      • 一旦迭代器的 __next__() 方法引发了 StopIteration,它必须一直对后续调用引发同样的异常。 不遵循此行为特性的实现将无法正常使用。
  • 也就是说,一个对象只要支持上面两个方法,就是迭代器。
class PowTwo:
    """Class to implement an iterator
    of powers of two 二的幂"""

    def __init__(self, max=0):
        self.max = max

    def __iter__(self):
        self.n = 0
        return self

    def __next__(self):
        if self.n <= self.max:
            result = 2 ** self.n
            self.n += 1
            return result
        else:
            raise StopIteration

PowTwo(3)
# <__main__.PowTwo at 0x7f84823bdf60>

[*PowTwo(3)]
# [1, 2, 4, 8]

n = PowTwo(3)
it = iter(n)

from collections import abc
isinstance(it, abc.Iterator)
# True

next(it) # 1
next(it) # 2  
next(it) # 4 
next(it) # 8 
next(it) # StopIteration

此外,还可以实现一个无限的迭代器,即元素是无限的,永远迭代不完。以下我们实现是一个无限偶数迭代器:

class Even:
    """Infinite iterator to return all
        Even numbers"""

    def __iter__(self):
        self.num = 2
        return self

    def __next__(self):
        num = self.num
        self.num += 2
        return num

# 注意!这个看就行,别执行,会死循环
[*Even()]

e = iter(Even())

next(e) # 2
next(e) # 4
next(e) # 6
next(e) # 8
next(e) # 10
# ...

内容函数 iter() 也可以生成无限迭代器,在传入两个参数的形式中,调用 callable 直到它返回 sentinel(哨兵,这里设置一个它不可能到达的值)。如:

int()
# 0

inf = iter(int,1)
next(inf) # 0
next(inf) # 0

在处理此类迭代器时,我们必须小心,注意要设置终止条件,否则非常容易造成死循环。

使用迭代器的优点是可以节省资源,比如上例中,我们可以在不将整个数字系统存储在内存中的情况下获得所有偶数。我们可以在有限的内存中拥有无限的内容项(理论上)。

总结下,迭代器的特点:

  • 惰性:迭代器并不是把所有的元素提前计算出来,而是在需要的时候才计算返回。
  • 支持无限个元素:它创建是一个规则,由于是惰性的,你永远可能不会把所有元素全部使用,而列表等容器没法容纳无限个元素的
  • 节省空间:迭代器惰性的特点,存储的是规则算法,因此不会占用太多内存
  • 迭代器同时也是可迭代对象
  • 迭代器遍历完一次就不能从头开始了,用完即销毁,对项的使用是「一次性」的

itertools 库

Python 内置库 itertools 中的大多数函数是返回各种迭代器对象,如果自己去实现同样的功能,代码量会非常大,而在运行效率上反而更低,因此,我们很有必要了解一下这个标准库。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python中的循环迭代器指的是使用`for`循环来遍历可迭代对象的过程。在Python中,通过`for`循环遍历可迭代对象时,实际上是通过迭代器来实现的。迭代器是一种特殊类型的对象,它可以按需生成值,直到没有更多的值可生成为止。 在Python中,`for`循环的工作原理是通过调用可迭代对象的`iter()`函数来获取一个迭代器,然后在每次循环中使用`next()`函数来获取迭代器的下一个元素,并将该值赋给循环变量,然后执行循环体。当迭代器耗尽时,会引发`StopIteration`异常,该异常会在内部被捕获并结束循环。需要注意的是,如果有其他类型的异常发生,它们将被正常传递。 如果想在Python中构建自己的迭代器,可以定义一个类,并在类中实现`__iter__()`和`__next__()`方法。`__iter__()`方法返回一个迭代器对象本身,而`__next__()`方法用于获取下一个元素。当没有更多的元素可生成时,可以在`__next__()`方法中引发`StopIteration`异常。 总结来说,Python中的循环迭代器是通过调用可迭代对象的`iter()`函数获取迭代器,并使用`next()`函数来获取迭代器的下一个元素的过程。自定义迭代器可以通过在类中实现`__iter__()`和`__next__()`方法来实现。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Python教程:迭代器的正确使用方法](https://blog.csdn.net/qdPython/article/details/126288647)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *3* [Python迭代器(Iterator)](https://blog.csdn.net/weixin_45068714/article/details/126863082)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值