Python生成器与迭代器详情

 更新时间:2021年11月2日 00:00  点击:2186 作者:一碗周

1、生成器

现在可以通过生成器来直接创建一个列表,但是由于内存的限制,列表的容量肯定是有限的,如果我们需要一个包含几百个元素的列表,但是每次访问的时候只访问其中的几个,那剩下的元素不使用就很浪费内存空间。

这个时候生成器(Generator)就起到了作用,他是按照某种算法不断生成新的数据,直到满足某一个指定的条件结束

得到生成式的方式有如下几种:

通过列表生成式来得到生成器,示例代码如下:

g = (x for x in range(10))  # 将列表生成列的[]改变成为()
# 打印其类型
print(type(g))  # <class 'generator'>
# 调用其元素
print(g.__next__())  # 0
print(g.__next__())  # 1
print(g.__next__())  # 2
print(g.__next__())  # 3
print(g.__next__())  # 4
# 使用.__next__的方式调用
print(next(g))  # 5
print(next(g))  # 6
print(next(g))  # 7
print(next(g))  # 8
print(next(g))  # 9
# 使用next()的方法调用
print(next(g))  # 当数据调用不到时会报出错误 StopIteration

需要多少调用多少,不调用的不会生成,也就不会占用内存空间,可以使用循环结构来按照需要来调用

g = (x for x in range(10))  # 将列表生成列的[]改变成为()
skip = True  # 判断条件
count = 0  # 调用次数
while skip:
    count += 1  # 循环一次+1
    print(next(g))
    if count > 9:
        break  # 跳出循环

使用函数借助yield关键字来完成一个生成器,生成斐波那契数列的前20个数,示例代码如下:

def fun(length):
    a, b = 0, 1
    for _ in range(length):
        a, b = b, a + b
        yield a


fib = fun(20)
print(type(fib))  # <class 'generator'>  # 打印类型
count = 0
while count < 20:
    # 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765
    print(next(fib), "", end="")
    count += 1

流程如下:

在执行过程中,遇到yield关键字就会暂停执行,下次调用则继续从上次暂停的位置继续执行,因为是一个循环语句,所有会直接跳到for语句

如果在调用yield,需要给它传值,就要使用.send()方法了。

示例代码如下:

def fun(num):
    n = 0
    for i in range(num + 1):
        n += i
        ret = yield n
        print(f"这是+到{ret}的第{i + 1} 次")


g = fun(3)
print(g.send(None))
print(g.send('3'))
print(g.send('3'))
print(g.send('3'))
'''
---输出结果---
0
这是+到 3 的第 1 次
1
这是+到 3 的第 2 次
3
这是+到 3 的第 3 次
6
'''

send的加入可以使生成器更加灵活,但是需要注意的是第一次调用生成器的send()方法时,参数只能为None,否则会抛出异常。当然也可以在调用send()方法之前先调用一次next()方法,目的是让生成器先进入yield表达式。

2、迭代器与可迭代的生成器

可迭代的对象有生成器、元组、列表、集合、字典和字符串等

通过collectionsIterable函数结合isinstance(object, classinfo)来判断一个对象时不是可迭代的对象

迭代是访问集合元素的一种方式。迭代器是一个可以记住遍历的位置的对象。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。很生成器也是迭代器。

可以被next ()函数调用并不断返回下一个值的对象称为迭代器: Iterator ,可以使用isinstance()判断一个对象是否是Iterator对象:

注意:可迭代的不一定是生成器,但是生成器一定第可迭代的。

把元组、列表、集合、字典和字符串等Iterable变成Iterator可以使用iter()函数

IterableIterator****的区别是Iterable是可以作为for循环对象的统称;而Iterator对象需要被next()函数调用才不断返回下一个数据,直到没有数据时抛出StopIteration错误,而在这之前是不会知道其长度的,所以Iterator的计算是惰性的,只有next()函数叫他才会返回结果,Iterator甚至可以表示一个无限大的数据流,例如全体自然数。

from collections.abc import Iterable, Iterator
a = [1, 2, 3]
b = {1, 2, 3}
c = (1, 2, 3)
d = "123"
e = 123
f = (x for x in range(5))
# 打印数据类型
print(type(a))  # <class 'list'>
print(type(b))  # <class 'set'>
print(type(c))  # <class 'tuple'>
print(type(d))  # <class 'str'>
print(type(e))  # <class 'int'>
print(type(f))  # <class 'generator'>
print("-" * 20)

# 打印是否为可迭代对象
print(isinstance(a, Iterable))  # True
print(isinstance(b, Iterable))  # True
print(isinstance(c, Iterable))  # True
print(isinstance(d, Iterable))  # True
print(isinstance(e, Iterable))  # False
print(isinstance(f, Iterable))  # True
print("-" * 20)
# 除了字符串都是可迭代对象

# 打印是否是迭代器
print(isinstance(a, Iterator))  # False
print(isinstance(b, Iterator))  # False
print(isinstance(c, Iterator))  # False
print(isinstance(d, Iterator))  # False
print(isinstance(f, Iterator))  # True
# 只有f(生成器)是迭代器
print("-" * 20)


# 通过iter()将可迭代转换为迭代器
print(isinstance(iter(a), Iterator))  # True
print(isinstance(iter(b), Iterator))  # True
print(isinstance(iter(c), Iterator))  # True
print(isinstance(iter(d), Iterator))  # True

到此这篇关于Python生成器与迭代器详情的文章就介绍到这了,更多相关Python生成器与迭代器内容请搜索猪先飞以前的文章或继续浏览下面的相关文章希望大家以后多多支持猪先飞!

原文出处:https://juejin.cn/post/7024045651361169445

[!--infotagslink--]

相关文章

  • python opencv 画外接矩形框的完整代码

    这篇文章主要介绍了python-opencv-画外接矩形框的实例代码,代码简单易懂,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-09-04
  • Python astype(np.float)函数使用方法解析

    这篇文章主要介绍了Python astype(np.float)函数使用方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-06-08
  • 最炫Python烟花代码全解析

    2022虎年新年即将来临,小编为大家带来了一个利用Python编写的虎年烟花特效,堪称全网最绚烂,文中的示例代码简洁易懂,感兴趣的同学可以动手试一试...2022-02-14
  • python中numpy.empty()函数实例讲解

    在本篇文章里小编给大家分享的是一篇关于python中numpy.empty()函数实例讲解内容,对此有兴趣的朋友们可以学习下。...2021-02-06
  • python-for x in range的用法(注意要点、细节)

    这篇文章主要介绍了python-for x in range的用法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-05-10
  • Python 图片转数组,二进制互转操作

    这篇文章主要介绍了Python 图片转数组,二进制互转操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-09
  • Python中的imread()函数用法说明

    这篇文章主要介绍了Python中的imread()函数用法说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-16
  • python实现b站直播自动发送弹幕功能

    这篇文章主要介绍了python如何实现b站直播自动发送弹幕,帮助大家更好的理解和学习使用python,感兴趣的朋友可以了解下...2021-02-20
  • python Matplotlib基础--如何添加文本和标注

    这篇文章主要介绍了python Matplotlib基础--如何添加文本和标注,帮助大家更好的利用Matplotlib绘制图表,感兴趣的朋友可以了解下...2021-01-26
  • 解决python 使用openpyxl读写大文件的坑

    这篇文章主要介绍了解决python 使用openpyxl读写大文件的坑,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-13
  • pytorch::Dataloader中的迭代器和生成器应用详解

    这篇文章主要介绍了pytorch::Dataloader中的迭代器和生成器应用详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-04-30
  • python 计算方位角实例(根据两点的坐标计算)

    今天小编就为大家分享一篇python 计算方位角实例(根据两点的坐标计算),具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-04-27
  • python实现双色球随机选号

    这篇文章主要为大家详细介绍了python实现双色球随机选号,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-05-02
  • python中使用np.delete()的实例方法

    在本篇文章里小编给大家整理的是一篇关于python中使用np.delete()的实例方法,对此有兴趣的朋友们可以学习参考下。...2021-02-01
  • 使用Python的pencolor函数实现渐变色功能

    这篇文章主要介绍了使用Python的pencolor函数实现渐变色功能,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-03-09
  • python自动化办公操作PPT的实现

    这篇文章主要介绍了python自动化办公操作PPT的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-05
  • Python getsizeof()和getsize()区分详解

    这篇文章主要介绍了Python getsizeof()和getsize()区分详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-11-20
  • 解决python 两个时间戳相减出现结果错误的问题

    这篇文章主要介绍了解决python 两个时间戳相减出现结果错误的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-12
  • python实现学生通讯录管理系统

    这篇文章主要为大家详细介绍了python实现学生通讯录管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-02-25
  • PyTorch一小时掌握之迁移学习篇

    这篇文章主要介绍了PyTorch一小时掌握之迁移学习篇,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-09-08