Python第六章-函数05-迭代器&生成器
python作为一个既面向对象,又支持函数式编程的语言,函数的使用方面有很多特点。
比如:闭包,装饰器,迭代器等
函数的高级应用
容器:生活中常见的容器有哪些?袋子,盆子,水杯,书包,铅笔盒。。。
容器是一种把多个元素组织在一起的数据结构,容器中的元素可以逐个的迭代获取,可以用in,not in等关键字判断某个元素是否包含在容器中。在python中常见的容器对象有:
list
, tuple
, dict
, str
, set
容器你可以把它看做一个房子,一个柜子,一个盒子,里面可以塞任何东西,从技术角度来说,当他可以用来询问某个元素是否包含在其中时,那么这个对象就可以看做一个容器。
1 in [1, 2, 3] # True
4 not in [1, 2, 3, 4] # False
4 in {1, 2, 3} # False
4 not in {1, 2, 3, 4} # False
一、迭代器
回想一下,到目前为止,能用for循环进行遍历的数据类型主要有哪些呢?dict,tuple,str,set,list
等
1.1 可迭代对象
可迭代对象和容器一样是一种通俗的叫法,并不是指某种具体的数据类型,list
是可迭代对象,dict
是可迭代对象,set
也是可迭代对象。
这些可以直接作用于for
循环的对象统称为可迭代对象:Iterable
。
前面说的序列和集合类型也是基于这个原理
那么,如何判断一个对象是可迭代对象呢?方法是通过collections模块的Iterable类型判断:
from collections import Iterable
# str是否可迭代
print(isinstance("abc", Iterable)) # True
# list是否可迭代
print(isinstance([1,2,3], Iterable)) # True
# 整数是否可迭代
print(isinstance(123, Iterable)) # False
1.2 迭代器
现在已经有很多对象可以使用for
循环,而且相对于其他语言,pythonfor
循环的使用方式非常优雅,简洁和便利
for`循环的背后就是迭代器
迭代器使用遍及python,并且使用方式统一
但凡是返回一个迭代器的对象,都可以成为可迭代对象。比如range
对象。
1.3 迭代器的工作原理
使用迭代器的步骤简述如下:
- 调用内置函数
iter(container)
, 把容器作为参数传递进去,返回一个对象,这个对象就是一个迭代器对象。容器对象就是咱们前边说的str,list
等- 迭代器对象中有一个方法
__next()__
,这个方法每调用一次,就可以访问到容器中的一个元素,我们自己要调用的话,只需要调用内置函数next(it)
就可以了- 当容器中最后一个元素被迭代后, 再调用
__next()__
方法, 则会抛出一个StopIteration
异常,for
循环捕捉到这个异常后就可以终止循环了.
当运行代码:
list1 = [1, 2, 3]
for x in list1:
....
实际执行的情况是
1.3 使用迭代器访问字符串中的元素
s = "acdefgh"
# 获取字符串 s 的迭代器, 其实等价于 it = s.__iter__()
it = iter(s)
print(next(it))# 迭代第一个元素
print(next(it))
print(next(it))
print(next(it))
print(next(it))
1.4 使用迭代器访问列表中的元素
s = [10, 30, 40, 20, 2]
it = iter(s)
print(next(it)) # 10
print(next(it)) # 30
print(next(it)) # 40
二、生成器
生成器算的上是python语言中最吸引人的特性之一,生成器其实是一种特殊的迭代器,不过这种迭代器更加优雅。他只需要一个yield关键字。生成器一定是迭代器(反之不成立),因此任何生成器也是以一种懒加载的模式生成值。
generator
(生成器)是一个简单且强大的创建迭代器的工具
生成器除了使用yield
之外, 就像一个正常的函数, 想在任何地方返回数据, 只需要添加yield
就可以了.
我们调用next()
函数, 一旦碰到yield
则返回yield
后的数据, python 并且可以保存当前的状态和位置, 下次再调用next()
, 则继续从此处执行.
# 生成能够迭代整数 1-n 的迭代器函数. 调用这个方法, 方法内的代码并不会立即执行, 而是返回一个生成器对象
def foo(n):
for i in range(1, n):
yield i # 每次碰到 yield, 则在此暂停, 并保存这个位置
for i in foo(20):
print(i)
当然也可以使用下面的方式去使用生成器函数
def foo(n):
for i in range(1, n):
yield i # 每次碰到 yield, 则在此暂停, 并保存这个位置
it = foo(20)
print(next(it))
print(next(it))
1.2.1 生成器表达式
生成器表达式(Generator Expressions), 是一个对象, 他执行的结果和以前学习的列表推导类似, 但会迭代的生成结果.
他的语法也与列表类似, 只是需要把以前的[]
换成()
语法:
it = (express for item in iterator)
def foo(n):
for i in range(1, n + 1):
yield i
# foo(20)返回的迭代器生成一个新的迭代器
it = (x * x for x in foo(20))
for y in it:
print(y)
1.2.2 生成器表达式和列表的差异
从写法上来看,生成器表达式使用()
, 而列表用[]
. 但是他们之间还是有很重要的差异.
他们的主要区别在于其中的元素(数据)的生成时间不同!
- 列表创建成功之后, 那么他里面的元素也已经创建成功, 而且是实实在在的占据着内存! 也就是说, 从物理上来看他们已经存在了.
- 而生成器表达式不一样, 仅仅是创建了一个生成器而已, 那些元素还没有创建. 只有当你使用
for
或者next()
的时候才会根据需要来创建元素. - 所以, 生成器不可能有添加, 删除等这些方法.
- 如果数据量比较大的时候, 使用生成器表达式的性能要好于列表.
- 列表推倒只能生成列表, 而生成器表达式可以根据需要生成任何类型的序列.
Python第六章-函数05-迭代器&生成器的更多相关文章
- Python第六章-函数06-高阶函数
函数的高级应用 二.高阶函数 高级函数, 英文叫 Higher-order Function. 那么什么是高阶函数呢? 在说明什么是=高阶函数之前, 我们需要对函数再做进一步的理解! 2.1 函数的本 ...
- Python第六章-函数01-函数的概念和使用
函数 为了便于程序的维护和更好的实现模块化,好的程序都会分解为很多函数. 可以这么说,对于任何的编程语言,函数都是一个非常重要的概念. python 不仅简化了函数的定义过程,而且还大量借鉴了其他函数 ...
- Python第六章-函数02-函数的作用域
函数 三.作用域规则 有了函数之后,我们必须要面对一个作用域的问题. 比如:你现在访问一个变量,那么 python 解析器是怎么查找到这个变量,并读取到这个变量的值的呢? 依靠的就是作用域规则! 3. ...
- Python第六章-函数04-递归函数和拉姆达表达式
五.递归函数 什么叫递归(recusive)? 你拿两个镜子互相面对着, 然后去看镜子, 会发现每个镜子中很多个镜子, 层层的嵌套, 无穷尽, 这就是一种递归! 从前有坐山, 山里有座庙, 庙里有个老 ...
- 简学Python第六章__class面向对象编程与异常处理
Python第六章__class面向对象编程与异常处理 欢迎加入Linux_Python学习群 群号:478616847 目录: 面向对象的程序设计 类和对象 封装 继承与派生 多态与多态性 特性p ...
- python第六章:三大利器(装饰器,迭代器,生成器)--小白博客
python装饰器 什么是装饰器?在不修改源代码和调用方式的基础上给其增加新的功能,多个装饰器可以装饰在同一个函数上 # 原理(个人理解):将原函数(bar)的内存地址重新赋值,进行覆盖.新值为装饰器 ...
- Python函数系列-迭代器,生成器
一 迭代器 一 迭代的概念 #迭代器即迭代的工具,那什么是迭代呢?#迭代是一个重复的过程,每次重复即一次迭代,并且每次迭代的结果都是下一次迭代的初始值 while True: #只是单纯地重复,因而不 ...
- 《Python 学习手册4th》 第十六章 函数基础
''' 时间: 9月5日 - 9月30日 要求: 1. 书本内容总结归纳,整理在博客园笔记上传 2. 完成所有课后习题 注:“#” 后加的是备注内容 (每天看42页内容,可以保证月底看完此书) “重点 ...
- 【Python】【容器 | 迭代对象 | 迭代器 | 生成器 | 生成器表达式 | 协程 | 期物 | 任务】
Python 的 asyncio 类似于 C++ 的 Boost.Asio. 所谓「异步 IO」,就是你发起一个 IO 操作,却不用等它结束,你可以继续做其他事情,当它结束时,你会得到通知. Asyn ...
随机推荐
- Tomcat生产环境应用
概要: Tomcat各核心组件认知 Tomcat server.xml 配置详解 Tomcat IO模型介绍 一.Tomcat各组件认知 Tomcat架构说明 Tomcat组件及关系详情介绍 Tomc ...
- notepad++ 字符处理: 字符前后删除 或 删除未包含字符串的行
字符串前后删除 删除str之后的所有字符用,打开替换(Ctrl+H) :str.*$ 删除str之前的所有字符用:^.*str 如果是其他字符就把str替换为其他字符 ---------------- ...
- Python -Selenium的安装和调用
安装selenium步骤: 1.安装pip(cmd命令行管理员方式): pip install pip 也可直接搜索pip,到官网下载安装 2.安装selenium(cmd命令行管理员方式): pip ...
- GZOJ 1361. 国王游戏【NOIP2012提高组DAY1】
国王游戏[NOIP2012提高组DAY1] Time Limit:1000MS Memory Limit:128000K Description 国王游戏(game.cpp/c/pas) [问题描述] ...
- deepin中安装pycharm过程
安装过程真的超级简单!一遍就会! 1.下载pycharm(下载地址):https://www.jetbrains.com/pycharm/ 2.在网址中找到对应的版本:在deepin中选择linux版 ...
- 整合Kafka+Flink 实例(第二部分 设计思路)
前 言 拖了蛮久了,一直说要接着上一部分写设计思路以及代码,因为自己技术底子薄弱,加上人又懒,所以一直没能继续,今天补上设计思路及部分代码,后面有时间我会再补充一些应用性的功能,的确有些忙,希 ...
- 复盘MySQL分页查询优化方案
一.前言 MySQL分页查询作为Java面试的一道高频面试题,这里有必要实践一下,毕竟实践出真知. 很多同学在做测试时苦于没有海量数据,官方其实是有一套测试库的. 二.模拟数据 这里模拟数据分2种情况 ...
- 神奇的 SQL 之扑朔迷离 → ON 和 WHERE,好多细节!
开心一刻 楼主:心都让你吓出来了! 狮王:淡定,打个小喷嚏而已 前情回顾 神奇的 SQL 之 联表细节 → MySQL JOIN 的执行过程(一)中,我们讲到了 3 种联表算法:SNL.BNL 和 I ...
- Overt.GrpcTemplate.Service 模板使用教程
阅读这篇文章需要先阅读我的另外一篇文章,目前还未发布出来,待发布中... 1. Overt.GrpcTemplate.Service .Net Core 3.1 版本 模板名称改成 Overt.Grp ...
- Java多线程并发03——在Java中线程是如何调度的
在前两篇文章中,我们已经了解了关于线程的创建与常用方法等相关知识.接下来就来了解下,当你运行线程时,线程是如何调度的.关注我的公众号「Java面典」了解更多 Java 相关知识点. 多任务系统往往需要 ...