零基础学 Python(2018 版)
尹会生
前游戏公司技术总监,前新浪网技术经理
80146 人已学习
新⼈⾸单¥68
课程目录
已完结/共 72 讲
第一章 :Python介绍和安装 (3讲)
第二章 :Python基础语法 (3讲)
第四章 :条件与循环 (5讲)
第五章 :映射与字典 (2讲)
第六章 :文件和输入输出 (2讲)
第七章 :错误和异常 (1讲)
第九章 :模块 (1讲)
第十章 :语法规范 (1讲)
第十一章 :面向对象编程 (4讲)
第十二章 :多线程编程 (2讲)
第十六章 :综合案例 & 结课测试 (1讲)
特别放送 (1讲)
零基础学 Python(2018 版)
登录|注册
留言
20
收藏
沉浸
阅读
分享
手机端
回顶部
当前播放: 25 | 函数的迭代器与生成器
00:00 / 00:00
高清
  • 高清
1.0x
  • 2.0x
  • 1.5x
  • 1.25x
  • 1.0x
  • 0.75x
  • 0.5x
网页全屏
全屏
00:00
付费课程,可试看
01 | Python语言的特点
02 | Python的发展历史与版本
03 | Python的安装
04 | Python程序的书写规则
05 | 基础数据类型
06 | 变量的定义和常用操作
07 | 序列的概念
08 | 字符串的定义和使用
09 | 字符串的常用操作
10 | 元组的定义和常用操作
11 | 列表的定义和常用操作
12 | 条件语句
13 | for循环
14 | while循环
15 | for循环语句中的if嵌套
16 | while循环语句中的if嵌套
17 | 字典的定义和常用操作
18 | 列表推导式与字典推导式
19 | 文件的内建函数
20 | 文件的常用操作
21 | 异常的检测和处理
22 | 函数的定义和常用操作
23 | 函数的可变长参数
24 | 函数的变量作用域
25 | 函数的迭代器与生成器
26 | Lambda表达式
27 | Python内建函数
28 | 闭包的定义
29 | 闭包的使用
30 | 装饰器的定义
31 | 装饰器的使用
32 | 自定义上下文管理器
33 | 模块的定义
34 | PEP8编码规范
35 | 类与实例
36 | 如何增加类的属性和方法
37 | 类的继承
38 | 类的使用-自定义with语句
39 | 多线程编程的定义
40 | 经典的生产者和消费者问题
41 | Python标准库的定义
42 | 正则表达式库re
43 | 正则表达式的元字符
44 | 正则表达式分组功能实例
45 | 正则表达式库函数match与search的区别
46 | 正则表达式库替换函数sub()的实例
47 | 日期与时间函数库
48 | 数学相关库
49 | 使用命令行对文件和文件夹操作
50 | 文件与目录操作库
51 | 机器学习的一般流程与NumPy安装
52 | NumPy的数组与数据类型
53 | NumPy数组和标量的计算
54 | NumPy数组的索引和切片
55 | pandas安装与Series结构
56 | Series的基本操作
57 | Dataframe的基本操作
58 | 层次化索引
59 | Matplotlib的安装与绘图
60 | 机器学习分类的原理
61 | Tensorflow的安装
62 | 根据特征值分类的模型和代码
63 | 网页数据的采集与urllib库
64 | 网页常见的两种请求方式get和post
65 | HTTP头部信息的模拟
66 | requests库的基本使用
67 | 结合正则表达式爬取图片链接
68 | Beautiful Soup的安装和使用
69 | 使用爬虫爬取新闻网站
70 | 使用爬虫爬取图片链接并下载图片
强势回归:零基础学Python2022版来啦!
71 | 如何分析源代码并设计合理的代码结构&结课测试
本节摘要

课程源码、课件及课后作业地址:

https://gitee.com/geektime-geekbang/geekbangpython

登录 后留言

全部留言(20)

  • 最新
  • 精选
Kanner
老师、这个yield还是没懂为什么能对浮点数进行叠加、而且我试了一下把yield换成print、输出的内容也是一样的呀

作者回复: yield的主要用途是需要一个数据时,才产生一个,而不是把数据线一次性存入内存;相对于把数据提前定义成列表来使用,要极为节省系统资源。 一般访问生成器要使用next方法,也可以使用list方法一次性讲将所有值读取出来,但是一次性读取出来就和列表一样了,失去自身的优势。

2018-06-12
14
硕杨Sxuya
没有比较,不明白 yield 到底有什么区别。

作者回复: 通常一个函数返回执行结果使用的是return关键字,但是在实际使用中发现如果函数返回的内容非常多而且是按顺序每次只使用一个元素的话,我们需要把结果再处理成可迭代对象,例如返回一个列表,我们要使用for..in...的形式再对返回结果做处理,这时候可以使用yield关键字来返回,有效的避免了一次返回数据过多,占用较多内存的问题。这就是为什么有了return还要产生yield的原因了。这里还有一些注意事项,使用yield关键字的函数叫做生成器,他返回的结果是可迭代对象,只能读取一次。更多的原理请参考stackoverflow : https://stackoverflow.com/questions/231767/what-does-the-yield-keyword-do

2018-09-16
11
Rita
为什么当我把step改成0.2的时候,输出结果变成 10 10.2 10.399999999999999 10.599999999999998 10.799999999999997 10.999999999999996 11.199999999999996 11.399999999999995 11.599999999999994

作者回复: 出现这样计算结果的原因是浮点数缺乏精确性导致的,如在python中计算 1+0.2+0.2+0.2, 发现执行结果和你的经验不一样了吗? 不止在python语言中存在这样的问题,凡是实数计算都会存在无限的精度跟有限的内存之间的矛盾 在系统底层计算浮点数时是使用二进制经过了它的转换,就出现了你看到的“误差” 要想精确计算可以使用Decimal库,就可以避免这种情况了 from decimal import Decimal a = Decimal('1') b = Decimal('0.2') print(a+b+b+b)

2018-07-02
9
纪小旭
for in 会自动调用next()吗

作者回复: 这里看结果很相似,但是其底层实现是不一样的, for in 使用的是 __iter__ 魔术方法 next 使用的是 __next__ 魔术方法 我们把能for in 的对象称作可迭代Iterable 我们把又能for in 又能next 的对象称作迭代器 Iterator

2020-04-19
6
jacy
yeild的实现原理是怎样的呢,如何做到的暂存,是存放在当前的调用栈吗?

作者回复: 带yield的函数我们称为迭代器,这种函数返回的是一个固定的对象,叫迭代器对象,它和return的最大区别是,如果你需要返回无限序列,return会产生一个巨大的列表,很明显存在内存限制问题。所以引入了yield返回一个固定长度的值。 确实如你所说,python虚拟机有一个调用栈,以python3.7为例,在Python-3.7.0\Include\frameobject.h 17行定义了PyFrameObject结构体,用来保存最后执行的指令、异常和命名空间。 当新创建一个迭代器时会调用Python-3.7.0\Objects\genobject.c 817行 PyGen_New(PyFrameObject *f) 函数。 我们知道调用yield其实就是调用迭代器的next方法,也就是调用了gen_iternext(PyGenObject *gen)函数,最终调用的是152行的gen_send_ex(PyGenObject *gen, PyObject *arg, int exc) 函数。 这里的Py_INCREF(result)函数用于记录引用计数器并加一, *(f->f_stacktop++) = result 209行这里是参数压栈操作了。

2018-09-06
5
圣林
谢谢老师的讲解,上上一课里面的“可选参数”和“可变长参数”,再加上本节课的迭代器和生成器,自己看书的时候看了好几遍都无法理解,当一看到老师的视频讲解后豁然开朗,有种通透的感觉,这几个概念不过如此嘛~

作者回复: 是的,学习就是一种从不懂到懂,从陌生到熟悉的过程,但是要想透彻的掌握一门语言还要多了解它背后的原理和技术,继续努力吧

2018-07-31
5
Megahertz
# 函数的迭代器和生成器 list1 = [1, 2, 3] it = iter(list1) print(next(it)) print(next(it)) print(next(it)) # print(next(it)) # StopIteration # fix me: 为什么try except 不能捕获异常呢 try: print(next(it)) except Exception as e: print(e)

作者回复: 是可以捕获的,只是因为stopiteration异常没有额外的返回信息,导致你输出的e没有任何内容,让你误以为捕获失败,将e换成其他提示信息可以看到捕获正常

2018-08-10
3
我要养只猫
老师,我把yield i换成print(i)后,输出的结果中会掺杂 typeerror是怎么回事?

作者回复: 需要看到你的完整代码和报错信息,如果是按照演示的程序修改,会报错为frange是非迭代对象,也就是没有yield没有迭代功能,不能使用for in的语法调用

2018-07-15
2
夏圣龙Je suis été
尹老师您好,为了验证您说的print和yield的区别,我把第51行代码改成print,输出的结果是相同的,只不过在输出10、14.5、15.0的时候会报错,在这个例子中影响不大。谢谢。

作者回复: 多去尝试,yield还有扩展的用法,在掌握了基础用法之后可以通过官方文档加深对yield的理解

2020-04-16
1
Dean_其
老师咨询一下如果yield的作用是可以让函数停留在当次的迭代值,那么为什么我下面的代码执行一次的时候什么值的都没有,根据代码来看print应该至少显示值为1,而不会显示后面的值才对。 除非我把frange(1,10,2)改为next(frange(1,10,2))就会输出值为1,求解 def frange(start,stop,step): x = start while x < stop: print(x) yield x x += step frange(1,10,2)

作者回复: 通过type()查看frange会发现,当你调用只会frange会变成<class 'generator'>类型,而生成器类型是不会自动执行的,必须用next() 或者list()取其中的元素,和你想的会按顺序执行不太一样

2019-04-25
1
收起评论