python之路_生成器进阶及相关表达式

一、生成器中的send用法

  send可以把一个值作为信号量传递到生成器函数中,然后和__next__方法一样获取生成器中的值;在生成器执行伊始,只能先使用__next__;二者都是终于yield,而send需要始于一个未被返还的yield处,否则传递的数值将无法被接收。

1、求重复累加平均实例

def average():
    count=0
    toatal=0
    average=0
    while True:
        value=yield average
        toatal+=value
        count+=1
        average=toatal/count
g=average()
print(g.__next__())                           #激活了生成器,返回yield后面的average,为0
print(g.send(10))                             #把10传递给yield前的value,继续执行后面的代码,终于yield后面的average,返回10
print(g.send(20))                             #把20传递给yield前的value,继续执行后面的代码,终于yield后面的average,返回15
print(g.send(30))                             #..........
print(g.send(40))
print(g.send(50))

2、用send传值失败实例

def func():
    print(1)
    yield 2
    print(3)
    value = yield 4
    print(5)
    yield value

g = func()
print(g.__next__())                          #打印出1和返回2,然后在第一个yield处停止等待
print(g.send(88))                            #由于第一个yield处没有未被返回的值,故send传值失败,打印出3和返回4,在第二个yield处停止等待
print(g.__next__())                          #value无值传入,打印出5后在第3个yield处返回none

3、用next激活生成器计算累加平均值

def init(func):                              #在调用被装饰生成器函数的时候首先用next激活生成器
    def inner(*args,**kwargs):
        g=func(*args,**kwargs)
        next(g)
        return g
    return inner
@init
def average():
    mount=0
    total=0
    average=0
    while True:
        value=yield average
        total+=value
        average=total/mount
g_avg=average()
                                            # next(g_avg)   在装饰器中执行了next方法
print(g_avg.send(10))
print(g_avg.send(20))
print(g_avg.send(30))

二、列表表达式和生成器表达式

1、列表表达式

  简化代码,返回的必须是一个列表

#普通代码
result=[]
for i in [1,2,3]
    result.append[i*i]
print(result)

#列表表达式
print([i*i for i in [1,2,3]])

(1)30内能被3整除的数的实例

print([i for i in range(1,31) if i%3==0])

(2)找到嵌套列表中有两个‘e’的名字

names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'], ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']]
print([for list in names for name in list if name.count('e')==2])

2、生成器表达式

  把列表解析的[]换成()得到的就是生成器表达式;列表解析与生成器表达式都是一种便利的编程方式,只不过生成器表达式更节省内存

laomuji=('鸡蛋%s' %i for i in range(10))        #生成器表达式
print(laomuji)                                 #返回生成器地址<generator object <genexpr> at 0x000001E17AF23BA0>
print(next(laomuji))                           #输出结果为:鸡蛋0
print(laomuji.__next__())                      #输出结果为:鸡蛋1
print(next(laomuji))                           #输出结果为:鸡蛋2
                                               #next(laomuji)等价于laomuji.__next__()

3、字典推导式

#将字典键与值对调
mcase = {'a': 10, 'b': 34}
print({mcase[k]:k for k in mcase})

4、集合推导式

  自带去重功能,将列表解析式的[]换成{}得到集合推导式

print({i*i for i in [1,-1,2]})    #结果为{1,4}

 三、生成器表达式面试题

  生成器表达式得到是一个生成器 ,生成器只有在取值的时候才能返出值。如下实例得到生成器g的存储地址,并不会如愿得到(1,4,9,16)

g=(i**2 for i in [1,2,3,4])
print(g)

  面试实例:

posted @ 2017-09-05 18:41  骑猪走秀  阅读(217)  评论(0编辑  收藏  举报