列表生成器(列表生成式):

使用此种方式生成的列表会放在内存中占用内存

a = [x*2 for x in range(1, 11)]
print(a) # >>> [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
# 完成3步:1. 从列表中取出每一个元素
# 2. 对每一个元素操作
# 3. 放回列表中 # 这里对函数的操作,即 x*2 也可以用函数来代替
# def f(n):
# return n**2
#
# a = [f(x) for x in range(1, 11)]
# print(a)
 

生成器:值不在生成器中。(比喻:生成器是厨师,不调用的话就不给你做饭,即生成数据。)

  1. 优点是不占用内存,因此不能像列表一样直接根据索引取元素,只能按顺序一个一个取
  2. 生成器是可迭代对象 iterable。(元组,字典,列表,集合,生成器都是可迭代对象)
  3. 什么是可迭代对象:从现象上看能进行 for 循环的都是可迭代对象,但是本质上有_iter_()方法的才是可迭代对象。
  4. 生成器最难理解的是:generator 和函数的执行流程不一样。函数是顺序执行,遇到 return 语句或者最后一行函数语句就返回。而变成 generator 的函数,在每次调用next()的时候执行,遇到 yield 语句返回,再次执行时从上次返回的 yield 语句处继续执行。
  5. 生成器在创建的时候就已经决定了能计算出值的个数,调用 next 的次数超过这个值就会报StopIteration

生成器有两种实现方式:

# 第一种,使用小括号方式生成
s = (x*x for x in range(1, 11)) # 创建一个生成器
print(s) # <generator object <genexpr> at 0x000000FD2251A318> # 第二种,使用 yield
# foo() 是一个生成器对象。只要有 yield,foo()这种写法就不会再被当作函数执行
def foo():
print('ok1')
yield 1
print('ok2')
yield 2
# 没有return,默认 return None

既然说了生成器里面是没有值的,那么我们想要取得值的时候怎么办呢?用什么方法呢?(我感觉生成器就像是造出来的一个有生成值的作用的机器,你不去启动它,他就不会生成值。我们让生成器计算出值所调用的方法,就是一个启动机器生成值的办法。)

有以下方法:

1. 调用内部函数__next__()方法,这个时候生成器会帮我们计算出第一个值。接着调用,接着生成第 2 个值.....

但是不建议调用此方法,因为这是内部特殊的方法

s = (x*x for x in range(1, 11))  # 创建一个生成器

print(s.__next__())
print(s.__next__()) # >>> 1
# >>> 4

2. 使用 next()函数

#python2 中写法有区别:s.next()
print(next(s)) # 等价于 s.__next__() >>> 1
print(next(s))
#>>>1
#>>>4

记录一个自己遇到的问题:

 # foo() 是一个生成器对象。
def foo():
print('ok1')
yield 1
print('ok2')
yield 2 # next(foo()) 是等于 1 ,yield 相当于一个 return, 把 1 返回给了next(foo())。但是此处我们并没有将 next(foo()) 进行打印,因此不会输出 1 next(foo())
next(foo()) #疑问抛出:观察下面输出,为什么总是输出 ok1 呢,难道不应该接着向下执行吗??
#>>>ok1
#>>>ok1 # 再看另一种方式,这种方式便可以输出 ok1,ok2。
# 上面是 next(foo()),这样每次执行这个语句的时候,foo()会被重新初始化,因此每次都从第一步开始执行
g = foo()
next(g)
next(g)
#>>>ok1
#>>>ok2

学习完了 next()函数,接下来学习 send()函数。

在使用send()函数前,必须要进入这个生成器内。

send函数其实和next()一样,都是进入生成器内,并且也是遇到 yield 返回,返回值也是 yield 的值。但是send多了一个功能,send('hello')函数是传一个值进去,但是这个值要给谁呢?

答案:传给 yield 前边的变量。 如 count = yield 1。 如果 yield 前边没有变量来接收这个值,也不会报错。


def foo():
print('ok1')
count = yield 1
print(count)
print('ok2')
yield 2 g = foo() s = g.send(None) # 相当于next(b) 第一次 send 前如果没有 next,但是又需要进入这个生成器,只能传一个 send(None)。
print(s)
s = g.send('eeee')
print(s) output:

ok1
1
eeee
ok2
2


生成器实现斐波那契数列:

def fib(max):
n, before, after = 0, 0, 1
while n < max:
# print(before)
yield before
before, after = after, before + after
n += 1 g = fib(8) for i in g:
print(i)

yield 实现伪并发(包子代码)

import time
def consumer(name):
print("%s 准备吃包子啦!" %name)
while True:
baozi = yield print("包子[%s]来了,被[%s]吃了!" %(baozi,name)) def producer(name):
c = consumer('A')
c2 = consumer('B')
c.__next__()
c2.__next__()
print("老子开始准备做包子啦!")
for i in range(10):
time.sleep(1)
print("做了2个包子!")
c.send(i)
c2.send(i) producer("alex")

16 python 初学(生成器)的更多相关文章

  1. 孤荷凌寒自学python第四十五天Python初学基础基本结束的下阶段预安装准备

     孤荷凌寒自学python第四十五天Python初学基础基本结束的下阶段预安装准备 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 今天本来应当继续学习Python的数据库操作,但根据过去我自 ...

  2. Python中生成器和迭代器的区别(代码在Python3.5下测试):

    https://blog.csdn.net/u014745194/article/details/70176117 Python中生成器和迭代器的区别(代码在Python3.5下测试):Num01–& ...

  3. python中“生成器”、“迭代器”、“闭包”、“装饰器”的深入理解

    一.生成器 1.什么是生成器? 在python中,一边循环一边计算的机制,称为生成器:generator. 2.生成器有什么优点? 1.节约内存.python在使用生成器时对延迟操作提供了支持.所谓延 ...

  4. python中“生成器”、“迭代器”、“闭包”、“装饰器”的深入理解

    python中"生成器"."迭代器"."闭包"."装饰器"的深入理解 一.生成器 1.生成器定义:在python中,一边 ...

  5. python基础 生成器 迭代器

    列表生成式: a=[1,2,3] print a b=[i*2 for i in range(10)] #i循环10次,每一个i的值乘2就是列表中的值.列表生成式 print b >>[1 ...

  6. Python迭代器生成器与生成式

    Python迭代器生成器与生成式 什么是迭代 迭代是重复反馈过程的活动,其目的通常是为了逼近所需目标或结果.每一次对过程的重复称为一次"迭代",而每一次迭代得到的结果会作为下一次迭 ...

  7. python 列表生成器

    python 列表生成器 列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式. 一个循环 在C语言等其他语言中,for循环一般是这样的 ...

  8. python 迭代器 生成器

    迭代器 生成器 一 什么是迭代器协议 1.迭代器协议是指:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代 (只能往后走不能往前 ...

  9. python中和生成器协程相关的yield from之最详最强解释,一看就懂(四)

    如果认真读过上文的朋友,应该已经明白了yield from实现的底层generator到caller的上传数据通道是什么了.本文重点讲yield from所实现的caller到coroutine的向下 ...

随机推荐

  1. C#中try catch finally的执行顺序

    1.首先明确一点,就是不管怎样,finally一定会执行,即使程序有异常,并且在catch中thorw 了 ,finally还是会被执行. 2.当try和catch中有return时,finally仍 ...

  2. 有序列表ol,无序列表ul,定义列表dl

    ====================非常重要=================无序列表ul中有一个type属性四个属性值type="disc" 实心圆点(默认) type=&q ...

  3. 解决微信开发工具上trace无法检测到设备,一直停留在“正在搜索设备...”或者trace panel,choose device老出现device not found

    性能 Trace 工具 微信 Andoid 6.5.10 开始,我们提供了 Trace 导出工具,开发者可以在开发者工具 Trace Panel 中使用该功能. 使用方法 PC 上需要先安装 adb  ...

  4. Exception 和 Error 有什么区别么

    声明 本篇所涉及的提问,正文的知识点,全都来自于杨晓峰的<Java核心技术36讲>,当然,我并不会全文照搬过来,毕竟这是付费的课程,应该会涉及到侵权之类的问题. 所以,本篇正文中的知识点, ...

  5. 利用Syslog Watcher在windows下部署syslog日志服务器

    1.概述 syslog协议是各种网络设备.服务器支持的网络日志记录标准.Syslog消息提供有关网络事件和错误的信息.系统管理员使用Syslog进行网络管理和安全审核. 通过专用的syslog服务器和 ...

  6. 函数纹理(国际象棋棋盘纹理&粗布纹理)MFC

    函数纹理(国际象棋棋盘纹理&粗布纹理)MFC实现  源码百度云下载 国际象棋棋盘纹理(效果图见最后) //国际象棋纹理函数 //g(u, v) = a , 向下取整(8u)+向下取整(8v) ...

  7. 惰性求值——lodash源码解读

    前言 lodash受欢迎的一个原因,是其优异的计算性能.而其性能能有这么突出的表现,很大部分就来源于其使用的算法--惰性求值. 本文将讲述lodash源码中,惰性求值的原理和实现. 一.惰性求值的原理 ...

  8. Jenkins 配置CI/CD任务

    本文演示如何通过Jenkins创建CI/CD任务,部署一整套微服务体系结构,并运行在之前搭建的mini云平台上. 如果是初始尝试实践,可能需要参考 快速搭建云原生架构的实践环境 和 Jhipster技 ...

  9. UE3多参数函数实现

    基础宏定义 #define VARARG_EXTRA(A) A, #define VARARG_NONE #define VARARG_PURE =0 static inline DWORD Chec ...

  10. Windows服务器防火墙配置规范

    本文属于一篇内部规范文档,整理的初衷是为了规范.统一集团的Windows服务器(仅仅SQL Server数据库服务器)防火墙设置,仅仅供内部其它同事设置Windows防火墙时作为参考的文档资料.如有不 ...