python生成器

生成器

函数要想有返回值使用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}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值