python中yield的用法

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

首先咱们得了解一个东西叫迭代器,一般的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参数。spa

如今咱们能够来谈谈yield了,其实yield就至关于一个return,只是return返回的是值,可是yield返回的是生成器,除了这点其余都同样,因此return也好yield也好都只能用在函数中,不要出现这种代码了:code

for i in range(5):
    return i

因此要试验yield要在函数里实验,咱们能够试着构造一个生成器:对象

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

咱们试着输出结果,却发现没有输出,这是由于生成了一个生成器,并且生成的生成器是在初始状态,我们还没给他下指令他就不会开始生成,因此如今咱们给他一个指令blog

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)ci

好,那么接下来你可能又会有问题了,为何这个只生成了第一个数啊,不该该是遍历把全部的输出来吗,这就是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
相关文章
相关标签/搜索