| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> Python知识库 -> python进阶【必会】(一)---------你会用python的生成器吗? -> 正文阅读 |
|
[Python知识库]python进阶【必会】(一)---------你会用python的生成器吗? |
目录🍉前言:对于python初学者来说,当我们试图去看一些开源的项目时,总会因为一些高级用法而卡住,诸如带有"yield"关键字的生成器,带有"@"符号的装饰器等等。这时,我们就需要主动去弄懂这些高级的用法,以求得到更快的进步。 所以,我希望从python的生成器开始,逐步的去总结一些高级的用法来和大家一起交流学习。文章结合了一些实例,力求通俗易懂,希望大家能静下心来不要跳读,这样才能得到更大的收获。 🍉什么是生成器:在写python程序时,如果我们想要生成一组有规律的数据,可以利用for循环来生成并将数据存放在列表里,比如:
?但是,这种方式存在着一个问题。我们将全部数据都生成在列表里,可是很多时候我们不会全部的用到它们,这样,就浪费了内存空间。 所以,我们想,能不能按需的去执行这段代码,即每需要一个数据就去生成一个数据。换句话说,就是延缓这个for循环的执行过程,不让它一次跑完10轮,我们每调用它一次,它才执行一轮,才生成一个数据。 这就是生成器(generator)。 🍉如何创建生成器:理解了什么是生成器,那就来看如何创建一个生成器,下面介绍两种方法: 1)小括号创建法
?如图所示,我们将数据的生成规则用小括号围住,就创建了一个生成器类型的对象。 2)函数+yield关键字创建法有时,我们想要表示的生成规则比较复杂,不能用一行代码表示。这时我们就需要把它写成一个多行的函数,通过调用这个函数就会返回一个生成器对象。 举个例子,如果我们想要生成斐波那契数列的前10个数,正常的函数写法是这样的:
而如果我们在函数中加上关键字yield,就可以得到一个生成器,如图所示。
🍉如何使用生成器:现在我们创建好了一个生成器对象,该如何使用它呢,下面介绍三种使用生成器的方法。 1)利用next()语句:
之前提到,生成器的核心思想就是延缓执行过程,按需执行。当我们需要它执行了,就去调用 next()方法,它就会执行一轮。 那怎样才算执行一轮呢,这就用到了yield关键字,yield在函数体中就起到了标识停止位置的作用。 当我们第一次调用next函数时,会从头开始执行生成器函数体中的语句,直到遇到yield关键字时停止执行,这就算完成了一轮的执行,而第二次调用next函数,又会在之前的停止位置继续执行, 直到遇到下一个yield再停止。 这样,这个函数的执行进度就牢牢的控制在我们的手中,其中,next()就相当于启动按钮,而yield就相当于我们设置的断点。 为了让大家更直观的看到yield的作用,下面这个动图展示了程序的单步执行过程: 另外还要注意的是,对于一个生成器来说,如果它的循环轮次是有限的,则我们可以调用的next次数就是有限的,比如上例,我们定义的生成器规则是生成数列的前10项,则当我们第11次调用next时就会抛出StopIteration 2)利用send()语句:通过next()语句,我们实现了让生成器逐步的执行,但是如果我们想在每次执行时去给生成器传递参数,该怎么实现呢。这就需要要用到send()语句了,它不仅有着像next()语句一样的逐步执行功能,还支持参数的传递。 我们用 "生成器.send(要传递的参数)"这种方式来实现逐步执行+传递参数,我们传递的参数会被yield左边的变量接收。例:
为什么参数会在yield处被接收呢,因为我们每次用next(这里是send)调用生成器时,总会在上次停止的位置开始执行,而上次停止的位置就恰好在yield这个断点上。 正是因为这个原因,我们不能在第一次调用生成器时就传递参数,因为第一次调用是从函数的第一句话开始执行,而不是在yield的位置,没有变量来接收参数,所以我们第一次调用时总会将None放在参数位置。 既然提到了为生成器传递参数,那如何让生成器返回参数呢,很简单,将我们希望返回的值添加到yield后面即可,比如:
3)利用for循环语句读取:我们通过next/send语句与函数中的yield关键字实现了延缓执行,但是有的时候我们也会想让这种按需执行的方式再连贯起来,比如我们想要利用一个已有的生成器去创建一个新的生成器,这时我们就可以利用生成器的可迭代的特性,用for循环来连贯的执行。 比如下面的例子,我们通过遍历生成器a,又生成了一个新的生成器b。
?利用for循环这种方法来使用我们的斐波那契生成器:
🍉总结综合来看,我觉得最重要的一点,就是要理解好我们为什么需要生成器,即,为了去延缓一个多轮的执行过程,让这个过程不要一次执行完。那该如何去实现延缓呢,即,利用next/send的启动作用,以及yield的断点作用来实现。理解了这些后,大家可以结合我上面给出的例子,去实战一下,自己编写几个生成器,这样能够更深刻的体会到生成器的作用。 以上,就是我对python生成器的一点总结和理解,希望对大家有些帮助。如果您喜欢我的文章,请点赞关注,咱们一起学习一起进步!您的支持是我创作最大的动力!如有问题可以在评论区留言或者私信与我交流,我会尽力解答!咱们下篇文章见!? ? ? |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/23 4:12:51- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |