yeild是python的关键字。如果你要了解yield的作用,你必须要了解生成器(generators),了解生成器之前你需要了解什么是可迭代对象(iterables)。
当你创建一个列表,你可以遍历这个列表,读取它的每一个元素,逐个读取列表元素的过程称为迭代(iteration)。
mylist = [2,3,4,5]
for i in mylist:
print(i)
像这种可以使用for…in…语法区迭代的对象都是可以迭代的对象。像字典,列表,数组,字符串都是可以迭代的对象。
生成器是迭代器(iteratos),但是只能迭代一次,生成器不会将所有值存储在内存中,而是实时的生成这些值:
mygenerators = (i*i for i in range(3))
for i in mygenerators:
print(i)
将列推导式的[]变成了(),其他并没有做任何的改变。但是mygenerators已经不是列表而是生成器。生成器迭代一次之后就不能再次迭代。计算出0,然后并不保存结果和状态继续计算出1,最好计算出4,逐一生成。
这只是创建生成器的一种方式,另外一种方式就是我们今天的主角yield关键字。
def create_generator():
for i in range(3):
yield i*i
mygenerator = create_generator()
for i in mygenerator:
print(i)
yield是一个类似return的关键字。当我们调用这个函数的时候并不是返回计算的结果。而是返回一个生成器。只有迭代这个生成器的时候才会计算结果。
for i in mygenerator:第一次循环的时候函数执行到yield关键字位置,返回ii的值,然后将函数挂起(保存函数执行的状态)。for i in mygenerator:第二次循环时,将继续执行刚才的函数(挂起的位置),也就是执行生成器里面的for循环,返回ii的值,然后再次将函数挂起。直到生成器里没有值可以返回就结束。
yield可以返回值,但是不会结束函数的执行,如果函数后面还有代码,同样是可以执行的。
def test():
for i in range(3):
yield i
print(‘我是生成器’)
mygen = test()
for i in mygen:
print(i)
0
我是生成器
1
我是生成器
2
我是生成器
需要创建一个非常大的列表直接使用列表推导式可能会导致内存被耗尽,这代码是创建不了列表,电脑内存不足以保存这个列表。
[i for i in range(1000000000)]
但是可以使用生成器创建成功,需要使用的时候再从生成器中取出。
1、不会将所有数据取出来存入内存中,而是返回了一个对象,可以通过对象获取数据,用多少取多少,可以节省内存空间。
2、除了能返回一个值,还不会终止循环的运行
再用yield的写法效率比普通的列表效率高
def test():
for i in range(1,111000000):
if i%2 ==0:
yield i
def test1():
result =[]
for i in range(1,111000000):
if i%2 ==0:
result.append(i)
return result
0.8925411202393 #生成器的写法耗时
1.14441919322678223 #普通写法耗时