python中yield的用法

昨天看了许多条博客,同时问了大佬一些心中的疑惑,对这个yield心中有了些许的理解,虽然可能没有理解到他的内涵,但至少在使用时该如何使用还是有了些许了解,因此决定写出来分享

首先我们得了解一个东西叫迭代器,通常的for…in…循环中,in后面是一个数组,这个数组就是一个可迭代对象,类似的还有链表,字符串,文件。它可以是mylist = [1, 2, 3],也可以是mylist = [x*x for x in range(3)]。 它的缺陷是所有数据都在内存中,如果有海量数据的话将会非常耗内存。他们可以从内容从中一个一个的读取,这就是迭代。

接着我们需要了解迭代器里的一个特殊——生成器,生成器也是一个可以迭代的对象,但是生成器每个只能迭代一次(至于为什么后面会讲),这是他特殊的原因。因为用的时候才生成。比如 mygenerator = (x*x for x in   range(3)),注意这里用到了(),它就不是数组,而上面的例子是[]。生成器这里用的是小括号,而迭代器用的是中括号。

好了接下来得讲下他们的方法,不管是生成器还是迭代器,都可以使用他的方法,就是next(这个方法在python2里面是使用的时候是方法c.next(),在python3里面变为了函数next(c)),但是由于迭代器可以自动进行,相当于里面已经内嵌了这个方法,生成一个迭代器他可以自动往后迭代,但是生成器不一样,生成一个生成器的时候,他是定在初始状态的,这就需要我们的next来一步一步推动他们。他们还有一种方法是send(),这个相当于在next功能的基础上,再加了一个传递的功能,他可以传递参数给yield表达式,所以send(None)就相当于next参数。

现在我们可以来谈谈yield了,其实yield就相当于一个return,只是return返回的是值,但是yield返回的是生成器,除了这点其他都一样,所以return也好yield也好都只能用在函数中,不要出现这种代码了:

for i in range(5):
    return i

所以要试验yield要在函数里实验,我们可以试着构造一个生成器:

def y_test(x):
    for i in range(x):
        yield i
        print(i)
y_test(3)

我们试着输出结果,却发现没有输出,这是因为生成了一个生成器,而且生成的生成器是在初始状态,咱们还没给他下指令他就不会开始生成,所以现在我们给他一个指令

def y_test(x):
    for i in range(x):
        yield i
        print(i)
y_test(3)
c = y_test(3)
next(c)

诶,我们现在改造了后为什么还是显示没有输出,现在生成器是生成了但别忘了这是一个相当于return的函数,他实际上已经把值传进了内存,但是没有显示出来,我们可以用一个print把他显示出来

def y_test(x):
    for i in range(x):
        yield i
        print(i)
y_test(3)
c = y_test(3)
print(next(c))

现在我们就会看到它显示出来了(range这个函数生成了从1到n-1得数,比如range(5)生成了0.1.2.3.4)

好,那么接下来你可能又会有问题了,为什么这个只生成了第一个数啊,不应该是遍历把所有的输出来吗,这就是yield的作用了,这是因为生成了生成器,我们next他一次,他也就只会往前走一次,第二次就不走了,那我们就再来一次next看看会怎样:

def y_test(x):
    for i in range(x):
        yield i
        print(i)
y_test(3)
c = y_test(3)
print(next(c))
print(next(c))

这时候出现了三个值,这就要继续解释yield的原因了,每次我们使用一次next,他都会执行到第一个yield结束的位置,第二次用next推动他执行时,他就会从上一个yield执行完成的位置开始执行到下一个yield执行完成,在这里是在for循环里,下一个yield就是第二个循环里的yield,虽然是一样的语句,但是他们所在的循环次数不一样,所以yield就相当于返回值的同时,记住当前运行到的位置,下一次运行就从上一次运行到的位置开始运行,这也是为什么他只能遍历一遍的原因,因为在第二个next执行的时候,第一个next里的内容已经被抛掉了,内存里只有第二个yield执行的内容。

我们可以再看一例子来加深理解:

def f(x):
    for i in range(x):
        yield i
        print (i)
        yield i+1

c = f(5)
print(next(c))
print(next(c))
print(next(c)) 

根据上文的理解会输出四个值

符合前面的猜想,最后让我们来用一个斐波那契数列的例子来结束全文吧:

def fib(x):
    yield 1
    a,b = 1,1
    while x:
        a,b = b,a+b
        yield a
        x=x-1
for i in fib(5):
    print(i)

>>>runfile(‘F:/Python/exercise/pygame/yield_text.py‘, wdir=‘F:/Python/exercise/pygame‘)
1
1
2
3
5
8

原文地址:https://www.cnblogs.com/gausstu/p/9545519.html

时间: 2024-11-07 09:42:21

python中yield的用法的相关文章

python中yield的用法及生成器的理解

首先我要吐槽一下,看程序的过程中遇见了yield这个关键字,然后百度的时候,发现没有一个能简单的让我懂的,讲起来真TM的都是头头是道,什么参数,什么传递的,还口口声声说自己的教程是最简单的,最浅显易懂的,我就想问没有有考虑过读者的感受. 接下来是正题: 首先,如果你还没有对yield有个初步分认识,那么你先把yield看做“return”,这个是直观的,它首先是个return,普通的return是什么意思,就是在程序中返回某个值,返回之后程序就不再往下运行了.看做return之后再把它看做一个是

python中yield的用法详解——最简单,最清晰的解释

本文收自:冯爽朗 ,下面有博主名片 个人分类: python 首先我要吐槽一下,看程序的过程中遇见了yield这个关键字,然后百度的时候,发现没有一个能简单的让我懂的,讲起来真TM的都是头头是道,什么参数,什么传递的,还口口声声说自己的教程是最简单的,最浅显易懂的,我就想问没有有考虑过读者的感受. 接下来是正题: 首先,如果你还没有对yield有个初步分认识,那么你先把yield看做"return",这个是直观的,它首先是个return,普通的return是什么意思,就是在程序中返回某

Python中yield的用法详解

首先我要吐槽一下,看程序的过程中遇见了yield这个关键字,然后百度的时候,发现没有一个能简单的让我懂的,讲起来真TM的都是头头是道,什么参数,什么传递的,还口口声声说自己的教程是最简单的,最浅显易懂的,我就想问没有有考虑过读者的感受. 接下来是正题: 首先,如果你还没有对yield有个初步分认识,那么你先把yield看做"return",这个是直观的,它首先是个return,普通的return是什么意思,就是在程序中返回某个值,返回之后程序就不再往下运行了.看做return之后再把它

Python中“*”和“**”的用法 || yield的用法 || ‘$in’和'$nin' || python @property的含义

一.单星号 * 采用 * 可将列表或元祖中的元素直接取出,作为随机数的上下限: import random a = [1,4] print(random.randrange(*a)) 或者for循环输出: import random a = [1,4] for i in range(*a): print(i) ''' result : 1 2 3 ''' 二.双星号 ** 双星号 ** 可将字典里的“值”取出,如下例 class Proxy(object): def __init__(self,

[转]Python中yield的解释

转自: http://python.jobbole.com/83610/ 本文作者: 伯乐在线 - wklken .未经作者许可,禁止转载!欢迎加入伯乐在线 专栏作者. 翻译 来源于stackoverflow问答,原文链接 Here SN上面看到的,顺手翻译下,第一次翻译,好多地方翻的不是很好 :) 问题: 1 Python中yield关键字的作用是什么?它做了什么? 例如,我想理解以下代码 1 2 3 def node._get_child_candidates(self, distance,

python中enumerate()的用法

先出一个题目:1.有一 list= [1, 2, 3, 4, 5, 6]  请打印输出:0, 1 1, 2 2, 3 3, 4 4, 5 5, 6 打印输出, 2.将 list 倒序成 [6, 5, 4, 3, 2, 1] 3.将a 中的偶数挑出 *2 ,结果为 [4, 8, 12] 这个例子用到了python中enumerate的用法.顺便说一下enumerate在for循环中得到计数的用法,enumerate参数为可遍历的变量,如 字符串,列表等: 返回值为enumerate类. 示例代码如

Python中range的用法

Python中range的用法 函数原型:range(start, end, scan): 参数含义:start:计数从start开始.默认是从0开始.例如range(5)等价于range(0, 5); end:技术到end结束,但不包括end.例如:range(0, 5) 是[0, 1, 2, 3, 4]没有5 scan:每次跳跃的间距,默认为1.例如:range(0, 5) 等价于 range(0, 5, 1)

C#中yield return用法分析(转载自shichen2014)

本文实例讲述了C#中yield return用法,并且对比了使用yield return与不使用yield return的情况,以便读者更好的进行理解.具体如下: yield关键字用于遍历循环中,yield return用于返回IEnumerable<T>,yield break用于终止循环遍历. 有这样的一个int类型的集合: ? 1 2 3 4 static List<int> GetInitialData() {   return new List<int>(){

python中MySQLdb模块用法实例

篇文章主要介绍了python中MySQLdb模块用法,以实例形式详细讲述了MySQLdb模块针对MySQL数据库的各种常见操作方法,非常具有实用价值,需要的朋友可以参考下 本文实例讲述了python中MySQLdb模块用法.分享给大家供大家参考.具体用法分析如下: MySQLdb其实有点像php或asp中连接数据库的一个模式了,只是MySQLdb是针对mysql连接了接口,我们可以在python中连接MySQLdb来实现数据的各种操作. python连接mysql的方案有oursql.PyMyS