十三. Python基础(13)--生成器进阶

1 ● send()方法

 

2 ● send()函数的简单案例

def fun():

    print('*')

    value = yield 1

    print('**', value)

    yield 2

 

g = fun()

print(g.__next__())

# print(g.__next__()) # ** None

print(g.send("aaa")) # ** aaa

# print(g.send("bbb")) # 警示"StopIteration"异常, 因为此时"bbb"没有可以用来赋值的的yield表达式

'''

*

1

** aaa

2

'''

# send()和__next__()工作的起始位置是完全相同的

# send()可以把一个值作为信号量(semaphore)传到函数中去

# 在生成器执行伊始, 只能先用__next__()或send(None), 因为用send()传递非None参数的时候,在生成器中必须有一个未被赋值的yield表达式

# __next_()方法以及send()方法的数量 不同多于 yield表达式的数量, 否则警示异常StopIteration.

 

3 ● 计算累计平均数

def wrapper(func): # 这个装饰器中只做一件事:g.__next__; 或者next(g), 也就是激活生成器(next是内置函数)

    def inner(*args, **kwargs):

        g = func(*args, **kwargs) # 最好不要跟外面的创建的gen生成器重名

        g.__next__() # 也可以是g.send(None), 用来激活生成器

        return g

    return inner

 

@wrapper

def average_func():

    total = 0

    count = 0

    average = 0

    while True: # 这个while True可以让使用者一直使用send方法, 也就是调用这个函数的可生成一个取之不尽用之不竭的生成器, 注意这里不会造成死循环

        value = yield average

        total += value

        count += 1

        average = total/count

 

gen = average_func()

print(gen.send(30))

print(gen.send(50))

print(gen.send(10))

'''

30.0

40.0

30.0

'''

 

4 ● 列表推导式/字典推导式/集合推导式(没有元组推导式)

列表推导式:

for i in range(0, 21, 2)
if ]) # [0, 4, 16, 36, 64, 100]

字典推导式:

案例①:

dic = {'k1':'v1', 'k2':'v2'}

print({dic[key]: key
for key in dic})

# {'v1': 'k1', 'v2': 'k2'}

 

案例②:

dic = {'a': 10, 'b': 34, 'A': 7, 'Z': 3}

dic_new = {k.lower(): dic.get(k.lower(), 0) + dic.get(k.upper(), 0)
for k in dic.keys()}

print(dic_new)

# {'a': 17, 'b': 34, 'z': 3}

集合推导式: (自带去重的功能)

print({i**2 for i in [1, -1, 2]})

# {1, 4}

 

5 ● 生成器表达式

把列表解析的[]换成()得到的就是生成器表达式.

gen_list = (i**2 for i in range(0, 21, 2) if i < 11)

for i in gen_list:

    print(i)

'''

0

4

16

36

64

100

'''

dic = {'k1':'v1', 'k2':'v2'}

gen_a = (key for key in dic)

gen_b = (key for key in dic.items())

for i in gen_a:

    print(i)

for i in gen_b:

    print(i)

'''

k1

k2

('k1', 'v1')

('k2', 'v2')

'''

gen_col = (i**2 for i in {1, -1, 2})

for i in gen_col:

    print(i)

'''

1

4

1

'''

 

6 ● 面试题1

def demo():

    for i in range(4):

        yield i

 

g=demo()

 

g1=(i for i in g)

g2=(i for i in g1)

 

print(list(g1)) # [0, 1, 2, 3]

print(list(g2)) # []

 

7 ● 面试题2

def add(n,i):

    return n+i

 

def test():

    for i in range(4):

        yield i

 

g=test()

for n in [1,10]:

    g=(add(n,i) for i in g) # 生成器推导式

    print(list(g))

 

# [1, 2, 3, 4]

# []注意这一步是没有数跟10相加, 因此为空.

def add(n,i):

    return n+i

 

def test():

    for i in range(4):

        yield i

 

g=test()

for n in [1,10]:

    g=(add(n,i) for i in g)

 

print(list(g))

 

'''

① 上面的三个g是三个不同的迭代器

② 上面一段相当于:

n = 1

g=(add(1,i) for i in range(4)) # 1+0+1+2+3=7 # 生成器中的数据没有被获取, 因为生成器只有在被调用的时候才会生成相应的数据(用__next__()、 for、list调用, 或被其它函数调用), 反之就不会生成--惰性运算.

n = 10

g=(add(n,i) for i in g)

print(list(g))

'''

 

# [20, 21, 22, 23]

如果这里是:

n=1

g=(add(n,i) for i in g) # 生成器推导式

n=10

g=(add(n,i) for i in g)

n=5

g=(add(n,i) for i in g)

print(list(g))

 

那么相当于运行:

for n in [1,10,5]:

g=(add(n,i) for i in g) # 生成器推导式

print(list(g))

 

即:

n=1

g = (add(n,i) for i in g)

n=10

g = (add(n,i) for i in (add(n,i) for i in g))

n=5

g = (add(5,i) for i in add(n,i) for i in (add(n,i) for i in g))

 

# [15, 16, 17, 18]

 

十三. Python基础(13)--生成器进阶的更多相关文章

  1. 十二. Python基础(12)--生成器

    十二. Python基础(12)--生成器 1 ● 可迭代对象(iterable) An object capable of returning its members one at a time. ...

  2. 二十三. Python基础(23)--经典类和新式类

    二十三. Python基础(23)--经典类和新式类 ●知识框架   ●接口类&抽象类的实现 # 接口类&抽象类的实现 #①抛出异常法 class Parent(object):    ...

  3. python基础篇之进阶

    python基础篇之进阶 参考博客:http://www.cnblogs.com/wupeiqi/articles/5115190.html python种类 1. cpython  使用c解释器生产 ...

  4. (转)python基础学习-----生成器和迭代器

    在Python中,很多对象都是可以通过for语句来直接遍历的,例如list.string.dict等等,这些对象都可以被称为可迭代对象.至于说哪些对象是可以被迭代访问的,就要了解一下迭代器相关的知识了 ...

  5. Python全栈开发之路 【第五篇】:Python基础之函数进阶(装饰器、生成器&迭代器)

    本节内容 一.名称空间 又名name space,就是存放名字的地方.举例说明,若变量x=1,1存放于内存中,那名字x存放在哪里呢?名称空间正是存放名字x与1绑定关系的地方. 名称空间共3种,分别如下 ...

  6. Python基础—面向对象(进阶篇)

    通过上一篇博客我们已经对面向对象有所了解,下面我们先回顾一下上篇文章介绍的内容: 上篇博客地址:http://www.cnblogs.com/phennry/p/5606718.html 面向对象是一 ...

  7. Python基础之生成器、迭代器

    一.字符串格式化进阶 Python的字符串格式化有两种方式: 百分号方式.format方式,由于百分号的方式相对来说比较老,在社区里讨论format方式有望取代百分号方式,下面我们分别介绍一下这两种方 ...

  8. Python之路,Day8 - Python基础 面向对象高级进阶与socket基础

    类的成员 类的成员可以分为三大类:字段.方法和属性 注:所有成员中,只有普通字段的内容保存对象中,即:根据此类创建了多少对象,在内存中就有多少个普通字段.而其他的成员,则都是保存在类中,即:无论对象的 ...

  9. Python之路【第六篇】python基础 之面向对象进阶

    一 isinstance(obj,cls)和issubclass(sub,super) isinstance(obj,cls)检查是否obj是否是类 cls 的对象  和  issubclass(su ...

随机推荐

  1. Python生成pyd文件

    Python的脚本文件是开源的,量化策略的安全性没有保障.因此需要保护源码.那么要对Python代码进行混淆.加密保护. 混淆代码,我准备使用pyminifier.而加密处理,就比较麻烦. Pytho ...

  2. Redis持久化AOF和RDB对比

    RDB持久化 AOF持久化 全量备份,一次保存整个数据库 增量备份,一次保存一个修改数据库的命令 保存的间隔较长 保存的间隔默认一秒 数据还原速度快 数据还原速度一般 save会阻塞,但bgsave或 ...

  3. (转)C# Delegate.Invoke、Delegate.BeginInvoke

    Delegate的Invoke.BeginInvoke 1.Delegate.Invoke (委托同步调用) a.委托的Invoke方法,在当前线程中执行委托. b.委托执行时阻塞当前线程,知道委托执 ...

  4. 架构探险笔记11-与Servlet API解耦

    Servlet API解耦 为什么需要与Servlet API解耦 目前在Controller中是无法调用Servlet API的,因为无法获取Request与Response这类对象,我们必须在Di ...

  5. 架构探险笔记6-ThreadLocal简介

    什么是ThreadLocal? ThreadLocal直译为“线程本地”或“本地线程”,如果真的这么认为,那就错了!其实它就是一个容器,用于存放线程的局部变量,应该叫ThreadLocalVariab ...

  6. 59 Cookie 与 Session

    Cookie Cookie是由服务器创建,然后通过响应发送给客户端的一个键值对. 客户端会保存Cookie,并会标注出Cookie的来源(哪个服务器的Cookie). 当客户端向服务器发出请求时会把所 ...

  7. 在线linux 平台

    1.http://www.shiyanlou.com/[实验楼] 2.http://bellard.org/jslinux/[大牛平台]

  8. 牛客寒假算法基础集训营6 E 海啸

    题目链接点这里 这个题输入类型是第一次见,并没有把n和m的具体范围给你,但是给了n*m的范围,武断的设为1e6*1e6的二维数组铁铁WA,就将二维数组转换为一维数组 题目类型属于二维数组前缀和,有um ...

  9. mysql索引注意事项

    mysql使用索引的注意事项 1.索引不会包含有NULL值的列 只要列中包含有NULL值都将不会被包含在索引中,复合索引中只要有一列含有NULL值,那么这一列对于此复合索引就是无效的.所以我们在数据库 ...

  10. 关于final static修饰的常量部署后没有更新的问题

    出现问题的场景是这样的: 项目中有个专门放流程Key值常量的类FlowConstants.java,其中这些常量都用了final static 修饰.某天因为修改了流程,相应的key值也改变了,所以直 ...