生成器

生成器

1.yield

若函数体包含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

在函数内可以采用表达式形式的yield

>>> def eater():
...     print('Ready to eat')
...     while True:
...         food=yield
...         print('get the food: %s, and start to eat' %food)
...

可以拿到函数的生成器对象持续为函数体send值,如下

>>> g=eater() # 得到生成器对象
>>> g
<generator object eater at 0x101b6e2b0>
>>> next(e) # 需要事先”初始化”一次,让函数挂起在food=yield,等待调用g.send()方法为其传值
Ready to eat
>>> g.send('包子')
get the food: 包子, and start to eat
>>> g.send('鸡腿')
get the food: 鸡腿, and start to eat
针对表达式形式的yield,生成器对象必须事先被初始化一次,让函数挂起在food=yield的位置,等待调用g.send()方法为函数体传值,g.send(None)等同于next(g)
def MyGenerator():
        v = yield 1# yield:语句执行到yield就停止了 所以刚开始运行到这一句的时候v没有赋值为1,等到send(5)时(yield 1被视为传入的参数5) 此时这一句被执行,v=5
        v=yield v 
        b=yield v 
        v=yield v 
        c=yield b
gen = MyGenerator()
print (next(gen))
print (gen.send(5))# v = yield 1 ->v = 5 ,先yield v,未执行v = 这里的赋值语句
print (gen.send(7))# v = yield v ->v = 7 ,先yield v,未执行b = 这里的赋值
print (gen.send(5))# b = yield v ->b = 5 ,yield v(=7) ,未执行v = 这里的赋值
print (gen.send(7))# v = yield v ->v = 7 ,yield b(=5) 结束
def consumer():#generator
    r = ''
    while True:
        n = yield r#consumer通过yield拿到消息,处理,又通过yield把结果传回;
        if not n:
            return
        print('[CONSUMER] Consuming %s...' % n)
        r = '200 OK'
 
def produce(c):
    c.send(None)#首先调用c.send(None)启动生成器,yield一个''进去
    n = 0
    while n < 5:
        n = n + 1
        print('[PRODUCER] Producing %s...' % n)
        r = c.send(n)#一旦生产了东西,通过c.send(n)切换到consumer执行;
        print('[PRODUCER] Consumer return: %s' % r)#produce拿到consumer处理的结果,继续生产下一条消息;
    c.close()#produce决定不生产了,通过c.close()关闭consumer,整个过程结束。
 
c = consumer()
produce(c)

# [PRODUCER] Producing 1...
# [CONSUMER] Consuming 1...
# [PRODUCER] Consumer return: 200 OK
# [PRODUCER] Producing 2...
# [CONSUMER] Consuming 2...
# [PRODUCER] Consumer return: 200 OK
# [PRODUCER] Producing 3...
# [CONSUMER] Consuming 3...
# [PRODUCER] Consumer return: 200 OK
# [PRODUCER] Producing 4...
# [CONSUMER] Consuming 4...
# [PRODUCER] Consumer return: 200 OK
# [PRODUCER] Producing 5...
# [CONSUMER] Consuming 5...
# [PRODUCER] Consumer return: 200 OK

2.三元表达式

针对以下需求
def func(x,y):
    if x > y:
        return x
    else:
        return y

res=func(1,2)
print(res)

#等效于
res=x if x > y else y
print(res)

3.列表生成式

l = ['alex_dsb', 'lxx_dsb', 'wxx_dsb', "xxq_dsb", 'egon']
new_l=[]
for name in l:
    if name.endswith('dsb'):
        new_l.append(name)


new_l=[name for name in l if name.endswith('dsb')]
new_l=[name for name in l]

print(new_l)

把所有小写字母全变成大写
new_l=[name.upper() for name in l]
print(new_l)

把所有的名字去掉后缀_dsb
new_l=[name.replace('_dsb','') for name in l]
print(new_l)

2、字典生成式

keys=['name','age','gender']
dic={key:None for key in keys}
print(dic)

items=[('name','egon'),('age',18),('gender','male')]
res={k:v for k,v in items if k != 'gender'}
print(res)

3、集合生成式

keys=['name','age','gender']
set1={key for key in keys}
print(set1,type(set1))

4.生成器表达式

创建一个生成器对象有两种方式,一种是调用带yield关键字的函数,另一种就是生成器表达式,与列表生成式的语法格式相同,只需要将[]换成(),即:

(expression for item in iterable if condition)

对比列表生成式返回的是一个列表,生成器表达式返回的是一个生成器对象

g=(i for i in range(10) if i > 3)
强调:此刻g内部一个值也没有

print(g,type(g))

print(g)
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))
print(next(g))
with open('笔记.txt', mode='rt', encoding='utf-8') as f:
    # 方式一:
    # res=0
    # for line in f:
    #     res+=len(line)
    # print(res)

    # 方式二:
    # res=sum([len(line) for line in f])
    # print(res)

    # 方式三 :效率最高
    # res = sum((len(line) for line in f))
    # 上述可以简写为如下形式
    res = sum(len(line) for line in f)
    print(res)
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值