生成器
函数要想有返回值使用return关键字,函数体包含yield关键字,再调用函数,并不会执行函数体代码,得到的就是生成器对象
生成器也是迭代器
def my_range(start,stop,step=1):
print('start...')
while start < stop:
yield start
start+=step
print('end...')
g=my_range(0,3)
g # <generator object my_range at 0x104105678>
# 生成器内置有__iter__和__next__方法,所以生成器本身就是一个迭代器
g.__iter__
# <method-wrapper '__iter__' of generator object at 0x1037d2af0>
g.__next__
# <method-wrapper '__next__' of generator object at 0x1037d2af0>
# 可以用next(生成器)触发生成器所对应函数的执行
next(g) # 触发函数执行直到遇到yield则停止,将yield后的值返回,并在当前位置挂起函数
start...
0
next(g) # 再次调用next(g),函数从上次暂停的位置继续执行,直到重新遇到yield...
1
next(g) # 周而复始...
2
next(g) # 触发函数执行没有遇到yield则无值返回,即取值完毕抛出异常结束迭代
end...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
# 当然也可以用for循环进行循环取值
for i in my_range(0.2):
print(i)
# 返回0,1,2
yield关键字
yield关键字让我们可以自定义迭代器,yield不同于return,函数一旦到return就结束了,而yield可以保存函数的运行状态挂起函数,用来返回多次值,简单的说,对一个列表,你yield一个元素,就返回一个参数
# 写一个简单的yield的函数
def eat():
print('Ready to eat')
while True:
food=yield
print('get the food: %s' %food)
# 生成器对象的使用和取值
g=eat() # 得到生成器对象
g # 返回<generator object eater at 0x101b6e2b0>,这是一个生成器对象
next(g) # 需要事先”初始化”,让函数运行到food=yield(就是我们说的挂起),之后通过g.send()为其传值
Ready to eat
g.send('包子') # send本质上是将“包子”传给food变量,food再传给yield进行返回
# 返回get the food: 包子
g.send('鸡腿')
# 返回get the food: 鸡腿
# 传递多个值
def eater():
print('Ready to eat')
food_list=[]
while True:
food=yield food_list
food_list.append(food)
e=eater()
next(e)
Ready to eat
# []
e.send('a')
# ['a']
e.send('b')
# ['a', 'b']
e.send('c')
# ['a', 'b', 'c']
yield from关键字
def func():
lst = ['卫龙','老冰棍','北冰洋','牛羊配']
yield from lst
g = func()
print(g)
# 他会将这个可迭代对象(列表)的每个元素当成迭代器的每个结果进行返回。
print(next(g))
print(next(g))
print(next(g))
print(next(g))
'''
yield from ['卫龙','老冰棍','北冰洋','牛羊配']
等同于:
yield '卫龙'
yield '老冰棍'
yield '北冰洋'
yield '牛羊配'
'''
生成器表达式
生成器表达式是简化了生成器的写法,一些简单的生成器都可以使用生成器表达式
gen = (i**2 for i in range(10))
print(gen)
# 结果: <generator object <genexpr> at 0x0000026046CAEBF8>
小括号是生成器表达式,那么中括号、大括号都是什么呢,一个是列表推导式,一个是集合、字典推导式
列表推导式
# 循环模式
ls = [i for i in range(10)]
print(ls)
# [0,1,2,3,4,5,6,7,8,9]
# 可以添加条件进行筛选
# 筛选模式
ls = [i for i in range(10) if i>5]
print(ls)
# [6,7,8,9]
字典推导式与集合推导式
# 字典推导式
lst1 = ['jay','jj','meet']
lst2 = ['周杰伦','林俊杰','郭宝元']
dic = {lst1[i]:lst2[i] for i in range(len(lst1))}
print(dic)
{'jay':'周杰伦','jj':'林俊杰','meet':'郭宝元'}
# 字典推导式
lst = [1,2,3,-1,-3,-7,9]
s = {abs(i) for i in lst}
print(s)
# {1,2,3,7,9}