python迭代器与生成器

概述

迭代是数据处理的基石,扫描内存中放不下的数据时,我们需要找到一种惰性获取数据项的方式,即按需一次获取一个数据项。这就是迭代器模式。

在python中,所有集合都可以迭代。在python语言内部,迭代器用于支持:

(1)for循环

(2)构建和扩展集合类型

(3)逐行遍历文本文件

(4)列表推导,字典推导和集合推导

(5)元组拆包

(6)调用函数时,用*拆包

python没有宏,因此为了抽象出迭代器模式,需要改动语言本身,为此加入了yield用于构建生成器。所有生成器都是迭代器,反之则不是。迭代器用于从集合中取出元素,而生成器用于凭空产生元素。

iter函数

解释器需要迭代对象x时,会主动调用iter(x)。内置iter函数有以下作用:

(1)检查对象是否实现了__iter__方法,如果实现了就调用它,获取一个迭代器。

(2)如果没有实现__iter__方法,但是实现了_getitem__方法,python会创建一个迭代器,尝试按顺序(从索引0开始)获取元素。

(3)如果尝试失败,python抛出TypeError异常,通常会提示对象不可迭代。

任何序列都可以迭代,其原因是,它们都实现了__getitem__方法。其实,标准的序列也都实现了__iter__方法。

实现了__iter__方法,就认为对象是可以迭代的,此时,不需要创建子类,也不用注册,因为abc.Iterable类实现了__subclasshook__方法。

class Foo:
    def __iter__(self):
        pass


from collections import abc
print(issubclass(Foo, abc.Iterable))
f = Foo()
print(isinstance(f, abc.Iterable))

#结果
True
True

而只实现了__getitem__方法的类,虽然可以迭代,但是无法通过issubclass测验。

迭代对象之前显示检查对象是否可以迭代或许没有必要,毕竟尝试迭代不可迭代的对象时,会抛出对象不可迭代的异常。如果除了抛出异常还有进一步处理,可以使用try/catch块。

iter函数还可以传入两个参数,使用常规函数或任何可调用对象创建迭代器。这样使用时,第一个参数必须是可调用对象,用于不断调用,产出各个值,另一个值是哨符,这个是标记值,当可调用对象返回这个值时会抛出StopIteration异常,而不产生哨符。

使用iter函数掷筛子,指代掷出1点:

from random import randint
def d6():
    return randint(1, 6)

d6_iter = iter(d6, 1)
print(d6_iter)
for roll in d6_iter:
    print(roll)

#结果
<callable_iterator object at 0x00000264FD3C54A8>
4
4
2
5
5
5

可迭代对象

可迭代的对象:使用iter内置函数可以获取迭代器的对象。如果对象实现了能返回迭代器的__iter__函数,那么对象就是可以迭代的。序列都可以迭代;实现了__getitem__方法,而且参数是从零开始的索引,这种对象也可以迭代。

可迭代对象与迭代器的关系是:python从可迭代对象中获取迭代器。

迭代一个字符串,'ABC'

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值