python中的迭代器、生成器和可迭代对象

背景

看过很多篇关于迭代器和生成器的介绍,始终没有留下很深的印象。每次遇到关于迭代器和生成器的问题,还是很容易混淆,概念不清。好记性不如烂笔头,还是自己亲自整理敲一遍吧。

1. 迭代器(Iterator)

1.1 迭代器的定义和特征

定义:是一个可以记住遍历位置的对象;
特征:迭代器对象从集合的第一个元素开始访问,直到所有元素被访问完结束;
    迭代器只能往前,不能后退;
    具有inter()和next()方法。inter()方法返回迭代器本身;next()方法返回容器的下一个元素;
    当没有下一个元素时,会抛出Stopiteration异常
    字符串,列表,元组,字典都可以用于创建迭代器
调用方法:
    迭代器对象可以使用for循环进行遍历
    可以使用next()函数
l = [1, 2, 3, 4]

i = l.__iter__()     # 等同于i = iter(l)  列表调用iter()方法返回迭代器对象i
print(i.__next__())  # 等同于print(next(i))  输出 1
print(type(i))       # <class 'list_iterator'> 迭代器对象
p = iter(i)          # 迭代器调用iter()方法
print(type(p))       # <class 'list_iterator'> 迭代器对象
print(next(i))       # 输出 2
print(next(i))       # 输出 3
print(next(i))       # 输出 4
# print(next(i))       # 抛出StopIteration异常

k = iter(l)
for t in k:          # 使用for调用迭代器值,依次输出1, 2, 3, 4,不会抛出异常
    print(t)

for t in k:          # 因上面的for循环已经将迭代器中值取完,再次遍历,无输出
    print(t)

1.2 如何通过类创建一个迭代器

    把一个类作为一个迭代器使用需要在类中实现__iter__()与__next__()方法
__iter__()方法返回一个特殊的迭代器对象,这个迭代器对象实现了__next__()方法,
并通过StopIteration异常标识迭代的完成。
__next__()方法会返回下一个迭代器对象

示例:创建一个返回数字的迭代器,初始值为1,逐步递增1:

class MyNumbers:
    def __iter__(self):
        self.a = 1
        return self
    def __next__(self):
        x = self.a
        self.a += 1
        return x

mynum = MyNumbers()
# myiter = iter(mynum)
myiter = mynum.__iter__()
print(type(myiter))
print(next(myiter))          # 输出 1
print(next(myiter))          # 输出 2
print(next(myiter))          # 输出 3
print(next(myiter))          # 输出 4
print(next(myiter))          # 输出 5
StopIteration异常用于标识迭代的完成,防止出现无限循环的情况,在__next__()方法中我们可以设置在完成指定循环次数后触发StopIteration异常来结束迭代

示例:在next()方法中增加StopIteration异常

class MyNumbers:
    def __iter__(self):
        self.a = 1
        return self
    def __next__(self):
        if self.a <= 20:
            x = self.a
            self.a += 1
            return x
        else:
            raise StopIteration

mynum = MyNumbers()
myiter = mynum.__iter__()
for x in myiter:
    print(x)        # 依次输出 1,2,3...20

2. 生成器(generator)

2.1 生成器定义

使用了yield关键字的函数被称为生成器;跟普通函数不同的是,生成器是一个返回迭代器的函数,
只能用于迭代器操作,可以理解为:生成器也是一种迭代器,在每次迭代时返回一个值,直到抛出StopIteration异常。

2.2 生成器构造

有两种构造方式
(1). 生成器表达式:和列表推导式类似,生成器表达式使用()而不是[],例如:
l = (x for x in range(5))
print(type(l))              # <class 'generator'>
for i in l:                 # 依次输出 0 1 2 3 4
    print(i)
(2). 含有yield关键字的函数
# 含有yield关键字的函数(斐波那契数列)
def fib(n):
    a, b, counter = 0, 1, 0
    while True:
        if counter > n:
            return
        yield a
        a, b = b, a+b
        counter += 1
f = fib(5)              # f是一个迭代器对象
print(type(f))          # <class 'generator'>
for i in f:
    print(i)            # 依次输出 0 1 1 2 3 5

3. 可迭代对象(Iterable)

3.1 可迭代对象定义

可遍历的对象,即能够使用for循环遍历的对象。python常见的可迭代对象有:列表、元组、字符串、集合、range、字典等;生成器和迭代器也可以用for遍历,所以迭代器和生成器都是可迭代对象

3.2 判单一个对象是否为可迭代对象

直接尝试iter(object),如果没有报错,则说明object是可迭代对象
l = [1, 2, 3]
b = 3
iter(l)         # 无报错
iter(b)         # TypeError: 'int' object is not iterable

4. 三者之间的关系

在这里插入图片描述

1). 可迭代对象包含迭代器,生成器,字典等可遍历的类型数据;说明生成器和迭代器一定是可迭代对象,反之则错
2). 可迭代对象调用__iter__方法就返回一个迭代器
3). 可迭代对象无法使用next()方法
4). 迭代器和生成器都有iter和next方法,生成器是特殊的迭代器
5). 含有yield关键字的函数,这个函数其实就是生成器
  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值