生成器
生成器就是自定义迭代器(自己造出来的)
yield关键字
yield的英文单词意思是生产,在函数中但凡出现yield关键字,再调用函数,就不会继续执行函数体代码,而是会返回一个值。
迭代器对象:具有__iter__
,__next__
的方法
def func():
yield 456 # yield会使函数func()变成生成器对象,因此他就具有__iter__方法
print(789) # yield会停止函数,当运行下一次next才会继续运行下面的代码
yield 101112 # 一个yield对应一个next
print(131415)
f=func() #生成器
print(f)# <generator object func at 0x000001F0E44237D8>
f_iter = f.__iter__()
print(f_iter.__next__())
print(f_iter.__next__())
print(f_iter.__next__())
yield三个特性
- yield可以把函数变成生成器(自定制的迭代器对象,具有__iter__和__next__方法)
- yield可以停止函数,再下一次next再次运行yield下面的代码
- 有n个yield生成器就有n个元素,就可以next n次, 第n+1次next会报错
return的特性
- 返回值
- 终止函数
return和yield
相同点:两者都是在函数内部使用,都可以返回值,并且返回值没有类型和个数的限制
不同点:return只能返回一次值;yield可以返回多次值
def func():
yield [1,1,23] # yield会使函数func()变成生成器对象,因此他就具有__iter__方法
print(789) # yield会停止函数,当运行下一次next才会继续运行下面的代码
yield 101112 # 一个yield对应一个next
print(131415)
g=func()
for i in g:
print(i)
[1, 1, 23]
789
101112
131415
用生成器自定制一个range方法
- 生成一个可迭代器对象 --- 》 我要把我的range函数变成一个可迭代对象(迭代器对象)
-
- 丢一个10进去,然后通过for循环的迭代next会丢出0,1,2,3,4,5,6,7,8, 9
def range(x):
count = 0
while count < x:
yield count
count += 1
# g = range(10)
# print(g.__next__())
# print(g.__next__())
# print(g.__next__())
# print(g.__next__())
# print(g.__next__())
# print(g.__next__())
# print(g.__next__())
# print(g.__next__())
for i in range(10):
print(i)
列表(列表推导式)元组(生成器表达式)的区别
列表就是一筐鸡蛋,元组就是一只老母鸡(节省空间)
lt = [i for i in range(10000000)]
print(lt)
g = (i for i in range(10000000))
print(g)
print(g.__next__()) # 把列表推导式的[]换成()
#省内存,一次只产生一个值在内存中