7.6 生成器
7.6 生成器
生成器:自定义的迭代器
7.6.1 yield关键字
类似于return,yield英文单词意思是生产,在函数中出现yield关键字,再调用函数,就不会继续执行函数体代码,而是会返回一个值。
yield关键字:接收值,但是不会结束函数,而是继续运行下一步下一行代码。
def func():
print(1)
yield #接收一个返回值后继续往下走,yield默认返回None,类似于return
print(2)
yield
#func()相当于迭代器
g= func()
print(g.__next__())
# print(g.__next__())
1
None
- yield返回多个值
def func():
print('from 1')
yield 1,2
print('from 2')
yield ['a',1,2],2 #返回多个值用元组接收,类似return
g= func()
for k,v in g:
print(k,v)
from 1
1 2
from 2
['a', 1, 2] 2
- yield & return 的区别
- yield: 接收函数返回值,但是不会终止函数,然后继续下一行代码,直到return。类似于循环中的continue。使用yield关键字调用的函数变成生成器。
- return:接收函数返回值,直接结束函数。类似于循环中的break。使用return关键字调用的函数就是一个普通的函数。
print(range(10))
for i in range(10):
print(i)
print(range(10).__iter__().__next__())
range(0, 10)
0
1
2
3
4
5
6
7
8
9
0
- 使用yield关键字写range函数
def range(start,end, step=1):
#前两个形参只支持位置赋值。当range(10)情况不适用
count=start
while count<end:
yield count
count+=step
g=range(1,10,2)
for i in g:
print(i)
# 查找顺序:如果当前位置是局部,则查找顺序为:局部->全局->内置方法
# range查找顺序:从全局开始,全局找到了我们自定义的range函数,则不会去内置中查找。
1
3
5
7
9
但是上述代码不适用于range(10)情况,基于以上改进后如下;
#range(10),range(1,10),range(1,10,2)都适用
def range(*args):
start=0
step=1
#range(10)
if len(args)==1:
end=args[0]
# range(1,10)
elif len(args)==2:
start=args[0]
end=args[1]
#range(1,10,2)
elif len(args)==3:
start=args[0]
end=args[1]
step=args[2]
else:
raise ('所传实参超出实参个数') #raise方法抛错
count=start
while count<end:
yield count
count+=step
g=range(5,10,2)
print(list(g))
#if-else 时间复杂度几乎为0
# while for循环时间复杂度较高,while<for
[5, 7, 9]
7.6.2 生成器表达式与列表表达式
- 生成器表达式
tup=(i for i in range(10)) #生成器:相当于老母鸡
print(tup.__next__()) # 使用for循环和next方法打印所有元素
print(tup.__next__())
0
1
#接着迭代
for i in tup:
print(i)
2
3
4
5
6
7
8
9
- 列表表达式
lis=[i for i in range(10)] #相当于生成一筐鸡蛋
print(lis) #打印所有元素
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
- 生成器表达式与列表表达式的区别
- 生成器:使用for循环和next方法打印所有元素,生成大量数据用生成器表达式
- 列表:一次打印所有元素,数据少用列表
浙公网安备 33010602011771号