返回顶部
首页 > 资讯 > 后端开发 > Python >彻底理解 Python 生成器
  • 711
分享到

彻底理解 Python 生成器

生成器Python 2023-01-30 22:01:32 711人浏览 泡泡鱼

Python 官方文档:入门教程 => 点击学习

摘要

1. 生成器定义 在python中,一边循环一边计算的机制,称为生成器:generator。   2. 为什么要有生成器 列表所有数据都在内存中,如果有海量数据的话将会非常耗内存。 如:仅仅需要访问前面几个元素,那后面绝大多数元素占用的空

1. 生成器定义

python中,一边循环一边计算的机制,称为生成器:generator。

 

2. 为什么要有生成器

列表所有数据都在内存中,如果有海量数据的话将会非常耗内存。

如:仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。

如果列表元素按照某种算法推算出来,那我们就可以在循环的过程中不断推算出后续的元素,这样就不必创建完整的list,从而节省大量的空间。

简单一句话:我又想要得到庞大的数据,又想让它占用空间少,那就用生成器!

 

3.如何创建生成器

第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了一个generator:

>>> 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 0x1022ef630>

 创建Lg的区别仅在于最外层的[]()L是一个list,而g是一个generator。

 

方法二, 如果一个函数中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator。调用函数就是创建了一个生成器(generator)对象。

 

4. 生成器的工作原理

(1)生成器(generator)能够迭代的关键是它有一个next()方法,

  工作原理就是通过重复调用next()方法,直到捕获一个异常。

(2)带有 yield 的函数不再是一个普通函数,而是一个生成器generator。

  可用next()调用生成器对象来取值。next 两种方式 t.__next__()  |  next(t)。

  可用for 循环获取返回值(每执行一次,取生成器里面一个值)

  (基本上不会用next()来获取下一个返回值,而是直接使用for循环来迭代)。

(3)yield相当于 return 返回一个值,并且记住这个返回的位置,下次迭代时,代码从yield的下一条语句开始执行。

(4).send() 和next()一样,都能让生成器继续往下走一步(下次遇到yield停),但send()能传一个值,这个值作为yield表达式整体的结果

  ——换句话说,就是send可以强行修改上一个yield表达式值。比如函数中有一个yield赋值,a = yield 5,第一次迭代到这里会返回5,a还没有赋值。第二次迭代时,使用.send(10),那么,就是强行修改yield 5表达式的值为10,本来是5的,那么a=10

 

感受下yield返回值的过程(关注点:每次停在哪,下次又开始在哪)及send()传参的通讯过程,

思考None是如何产生的(第一次取值:yield 返回了 i 值 0,停在yield i,temp没赋到值。第二次取值,开始在print,temp没被赋值,故打印None,i加1,继续while判断,yield  返回了 i 值 1,停在yield i):

 

 

 

好了,话不多说,翠花,上栗子:

 1 #encoding:UTF-8  
 2 def yield_test(n):  
 3     for i in range(n):  
 4         yield call(i)  
 5         print("i=",i)      
 6     print("Done.")  
 7   
 8 def call(i):  
 9     return i*2  
10   
11 for i in yield_test(5):  
12     print(i,",")

  结果:

>>>   
0 ,  
i= 0  
2 ,  
i= 1  
4 ,  
i= 2  
6 ,  
i= 3  
8 ,  
i= 4  
Done.
>>>

 理解的关键在于:下次迭代时,代码从yield的下一条语句开始执行。

 

 总结

什么是生成器?

生成器仅仅保存了一套生成数值的算法,并且没有让这个算法现在就开始执行,而是我什么时候调它,它什么时候开始计算一个新的值,并给你返回。

 

 

练习题:

def count_down(n):
    while n >= 0:
        newn = yield n
        print('newn', newn)
        if newn:
            print('if')
            n = newn
            print('n =', n)
        else:
            n -= 1


cd = count_down(5)
for i in cd:
    print(i, ',')
    if i == 5:
        cd.send(3)

 

结果:

 

--结束END--

本文标题: 彻底理解 Python 生成器

本文链接: https://lsjlt.com/news/179766.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 彻底理解 Python 生成器
    1. 生成器定义 在Python中,一边循环一边计算的机制,称为生成器:generator。   2. 为什么要有生成器 列表所有数据都在内存中,如果有海量数据的话将会非常耗内存。 如:仅仅需要访问前面几个元素,那后面绝大多数元素占用的空...
    99+
    2023-01-30
    生成器 Python
  • 彻底理解Python list切片原理
    关于list的insert函数 list#insert(ind,value)在ind元素前面插入value 首先对ind进行预处理:如果ind<0,则ind+=len(a),这样一来ind就变成了正...
    99+
    2022-06-05
    切片 原理 Python
  • 彻底理解Redis持久化
    前言 大家都知道Redis一个内存数据库,它支持2种持久化方式:RDB(Snapshot 内存快照),AOF(append only file)。持久化功能将内存中的数据同步到磁盘来避免Redis发生异常导致数据丢失的情况。当Redis实...
    99+
    2017-07-16
    彻底理解Redis持久化
  • 彻底理解Java 中的ThreadLocal
     ThreadLocal是什么  早在JDK 1.2的版本中就提供Java.lang.ThreadLocal,ThreadLocal为解决多线程程序的并发问题提供了一种新的思路。使用这个工具类可以很简洁地编写出优美的多线程程序。 ...
    99+
    2023-05-31
    java threadlocal ava
  • 一文彻底理解js原生语法prototype,__proto__和constructor
    目录1 前言2 前置知识点 2.1 数据类型 2.2 判断是否是自身属性(hasOwnProperty)3 一点小思考3.1 修改 constructor 3.1.1 instanc...
    99+
    2024-04-02
  • 怎么彻底理解红黑树
    本篇内容主要讲解“怎么彻底理解红黑树”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么彻底理解红黑树”吧!二叉树满足以下两个条件的树就是二叉树:本身是有序树(若...
    99+
    2024-04-02
  • 如何彻底理解Go指针
    如何彻底理解Go指针,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。什么是指针简单点说,指针是指向另一个地址的值。这是教科书上的解释,但如果你转自一门不用谈论变量...
    99+
    2023-06-16
  • 彻底理解Spring注解@Autowired实现原理
    目录前言1、@Autowired注解用法2、@Autowired注解的作用到底是什么3、@Autowired注解是如何实现的自己实现一个注解4、@Autowired注解实现逻辑分析5...
    99+
    2024-04-02
  • AndroidOkHttp代理与路由的彻底理解
    目录代理什么是代理?代理的类型代理选择器路由什么是路由?路由数据库路由选择器RouteSelector 内部类 SelectionRouteSelector 成员变量Rou...
    99+
    2023-03-09
    Android OkHttp代理路由 Android OkHttp
  • 彻底理解golang中什么是nil
    nil是什么 相信写过Golang的程序员对下面一段代码是非常非常熟悉的了: if err != nil { // do something.... } 当出现不等于n...
    99+
    2024-04-02
  • 彻底解决AMD 无法运行android studio原生模拟器
    彻底解决AMD 无法运行android studio原生模拟器 问题描述 早期的amd不支持AMD运行android studio的原生模拟器,...
    99+
    2022-06-06
    Android Studio studio 模拟器 amd Android
  • 让你五分钟彻底理解Spring MVC
    目录概述MVC 架构模式传统 MVC 架构模式Java Web MVC 架构模式Spring MVC 架构模式Hello,Spring MVCSpring MVC 依赖引入Dispa...
    99+
    2024-04-02
  • 一文彻底理解Golang闭包实现原理
    目录前言函数一等公民作用域实现闭包闭包扫描闭包赋值闭包函数调用函数式编程总结前言 闭包对于一个长期写 Java 的开发者来说估计鲜有耳闻,我在写 Pyt...
    99+
    2024-04-02
  • 我用一张图彻底理解了Activity生命周期的含义(Android)
    Activity生命周期 1.图解Activity生命周期: 2.七个方法的含义 一、 onCreate :当活动第一次启动的时候,触发该方法...
    99+
    2022-06-06
    activity生命周期 activity Android
  • 正确理解python迭代器与生成器
    目录一、迭代器二、生成器三、生成器函数3.1、zip(可迭代对象1,可迭代对象2......)3.2、enumerate(iterable[,start])一、迭代器 迭代器就是iter(可迭代对象函数)返回的对象,...
    99+
    2022-06-02
    python 迭代器 python 生成器
  • 彻底理解JavaScript的原型与原型链
    目录前言基础铺垫prototypecontructor属性__proto__原型链提高总结后语前言 原型与原型链知识历来都是面试中考察的重点,说难不算太难,但要完全理解还是得下一定...
    99+
    2024-04-02
  • python中随机数底层如何生成
    在Python中,随机数是通过使用伪随机数生成器来生成的。伪随机数生成器是一个算法,它根据一种确定性的方法生成看似随机的数值序列。P...
    99+
    2023-09-04
    python
  • 带你彻底理解JavaScript中的原型对象
    目录一、什么是原型1.1 函数的原型对象1.2 使用构造函数创建对象二、与原型有关的几个属性和方法2.1 prototype属性2.2 constructor属性2.3 __prot...
    99+
    2024-04-02
  • 彻底弄懂Base64的编码与解码原理
    Base64是一种用于将二进制数据转换为可打印字符的编码方式。它使用64个字符来表示任意二进制数据,包括字母(大写和小写)、数字以及...
    99+
    2023-09-23
    Base64
  • 详解Python生成器和基于生成器的协程
    目录一、什么是生成器二、基于生成器的协程三、协程的注意点四、协程装饰器五、python3原生协程一、什么是生成器 Generator 1.生成器就是可以生成值的函数 2.当一个函数里...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作