Python学习-迭代器、生成器
一、迭代器
1. 可迭代对象
我们知道字符串、列表、元组、字典、集合都可以使用for语句进行循环遍历,然后输出每一个元素,这些都是可迭代对象。
检查对象是否是可迭代对象可以用两种方式去判断:
(1)使用dir()查看对象包含的方法和函数, 如果能找到__iter__, 那么这个对象就是一个可迭代对象
>>> lst = ['a', 'b', 'c']
>>> dir(lst) #查看对象包含的方法和函数
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
>>> dir(list) #查看类中声明的方法和函数
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
>>>
(2)使用isinstance进行判断
>>> from collections import Iterable
>>> lst = ['a', 'b', 'c']
>>> isinstance(lst, Iterable) #结果为True,为可迭代对象
True
iterable翻译: 可迭代的; 可重复的; 迭代的
此处只查看了列表类型对象, 其他类型的对象可以自己尝试.
2. 迭代器
概念: 可以被next()
函数调用并不断返回下一个值的对象称为迭代器:Iterator
。
所谓的迭代器就是具有next方法的对象. 在调用next方法时, 迭代器会返回它的下一个值. 如果next方法被调用, 但迭代器没有值可以返回, 就会引发一个StopIteration异常.
迭代器和可迭代对象有什么区别:
(1) 可迭代对象不一定是迭代器, 但迭代器一定是可迭代对象
(2) 可迭代对象有iter方法, 迭代器有iter和next方法; 可以使用iter方法将可迭代对象转为迭代器
(3) 迭代器是惰性的, 只有当你使用next方法去取值的时候, 它才会返给你一个值
判断对象是否是迭代器:
>>> from collections import Iterator
>>> isinstance((x for x in range(10)), Iterator)
True
>>> isinstance(['a', 'b'], Iterator)
False
>>> isinstance('hello', Iterator)
False >>> g = (x * 2 for x in range(5))
>>> isinstance(g, Iterator)
True
>>> next(g)
0
>>> next(g)
2
>>> next(g)
4
>>> next(g)
6
>>> next(g)
8
>>> next(g) # 没有值返回时, 抛出异常StopIteration
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>>
使用iter方法(或__iter__)将对象变为迭代器:
>>> lst = ['a', 'b', 'c']
>>> isinstance(lst, Iterator)
False
>>> lst_g = lst.__iter__()
>>> isinstance(lst_g, Iterator)
True
>>> for ele in lst_g:
... print(ele)
...
a
b
c
>>> dic = {'a': 1, 'b': 2}
>>> isinstance(dic, Iterator)
False
>>> dic_g = iter(dic)
>>> isinstance(dic_g, Iterator)
True
小结:
凡是可作用于for
循环的对象都是Iterable
类型;
凡是可作用于next()
函数的对象都是Iterator
类型,它们表示一个惰性计算的序列;
集合数据类型如list
、dict
、str
等是Iterable
但不是Iterator
,不过可以通过iter()
函数获得一个Iterator
对象。
二、生成器
1. 先介绍一下列表生成式 (内容粘贴自廖雪峰老师的官方网站)
列表生成式,是Python内置的非常简单却强大的可以用来创建list的生成式。
列表生成式即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式。
举个例子,要生成list [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
可以用list(range(1, 11))
:
>>> list(range(1, 11))
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
但如果要生成[1x1, 2x2, 3x3, ..., 10x10]
怎么做?方法一是循环:
>>> L = []
>>> for x in range(1, 11):
... L.append(x * x)
...
>>> L
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
但是循环太繁琐,而列表生成式则可以用一行语句代替循环生成上面的list:
>>> [x * x for x in range(1, 11)]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
写列表生成式时,把要生成的元素x * x
放到前面,后面跟for
循环,就可以把list创建出来,十分有用,多写几次,很快就可以熟悉这种语法。
for循环后面还可以加上if判断,这样我们就可以筛选出仅偶数的平方:
>>> [x * x for x in range(1, 11) if x % 2 == 0]
[4, 16, 36, 64, 100]
还可以使用两层循环,可以生成全排列:
>>> [m + n for m in 'ABC' for n in 'XYZ']
['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']
2. 生成器
通过列表生成式我们可以快速创建一个列表,这种方法生成列表,它会一次性的返回给我们全部元素,想想如果列表包含100万个元素,一次性返回会占用很大的内存空间,如果我们仅仅需要访问前面几个元素,这种方式生成的列表就比较浪费内存空间了。有没有一种方式,按照我们的需要,访问时给我们返回元素,不要像列表生成式一样一次全部返回。生成器就可以满足我们的这种需求,按需返回,可以调用next方法,生成器会返回它的下一个值,当没有值可以返回时,抛出StopIteration异常。实际使用中,我们一般使用for循环对生成器进行迭代。
在python中创建生成器:
(1)生成器函数
def func():
print('hello world')
yield 'world' #与定义的普通函数没有区别,只是含有yield关键字;函数中包含yield关键字即为生成器函数
print('hello china')
yield 'china' g = func()
print(next(g))
print(next(g))
print(g)
# 输出结果
hello world
world
hello china
china
<generator object func at 0x108ad3468>
(2)生成器表达式
只要把一个列表生成式的[]
改成()
,就创建了一个generator。
g = (x * x for x in range(5))
print(g)
for i in g:
print(i)
输出结果:
<generator object <genexpr> at 0x10a845468>
0
1
4
9
16 lst = ['a', 'b', 'c', 'd']
g2 = (x * 2 for x in lst)
print(g2)
while 1:
try:
print(next(g2))
except StopIteration:
break
输出结果:
<generator object <genexpr> at 0x10395b468>
aa
bb
cc
dd
Python学习-迭代器、生成器的更多相关文章
- Python学习——迭代器&生成器&装饰器
一.迭代器 迭代器是访问集合元素的一种方式.迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代器只能往前不会后退迭代器的一大优点是不要求事先准备好整个迭代过程中所有的元素.迭代器仅 ...
- python函数-迭代器&生成器
python函数-迭代器&生成器 一.迭代器 1 可迭代协议 迭代:就是类似for循环,将某个数据集内的数据可以“一个挨着一个取出来” 可迭代协议: ① 协议内容:内部实现__iter__方法 ...
- Python基础-迭代器&生成器&装饰器
本节内容 迭代器&生成器 装饰器 Json & pickle 数据序列化 软件目录结构规范 作业:ATM项目开发 1.列表生成式,迭代器&生成器 列表生成式 我现在有个需求,看 ...
- Python学习二(生成器和八皇后算法)
看书看到迭代器和生成器了,一般的使用是没什么问题的,不过很多时候并不能用的很习惯 书中例举了经典的八皇后问题,作为一个程序员怎么能够放过做题的机会呢,于是乎先自己来一遍,于是有了下面这个ugly的代码 ...
- 【python】迭代器&生成器
源Link:http://www.cnblogs.com/huxi/archive/2011/07/01/2095931.html 迭代器 迭代器是访问集合元素的一种方式.迭代器对象从集合的第一个元素 ...
- python学习之生成器
4.6 生成器Generrator 生成器本质就是迭代器.python社区生成器与迭代器是一种. 生成器与迭代器的唯一区别:生成器是我们自己用python代码构建的 4.6.1生成器初识 py ...
- python学习------迭代器协议和生成器
一.递归和迭代 递归:自己调用自己 举例解释:问路 A问B康明网络科技怎么走,B说我不是很清楚,我帮你问问C,C说我也不知道.我问问D,D说 就在兴隆.之后D返回结果给C,C返回结果给B,B返回结 ...
- day13 python学习 迭代器,生成器
1.可迭代:当我们打印 print(dir([1,2])) 在出现的结果中可以看到包含 '__iter__', 这个方法,#次协议叫做可迭代协议 包含'__iter__'方法的函数就是可迭代函数 ...
- python学习之- 生成器/迭代器
列表生成式写法: [ i*2 for i in range(10) ]也可以带函数 [ fun(i) for i in range(10) ] 生成器:一边循环一边计算的机制称为生成器.在常用函数中, ...
随机推荐
- pip安装ansible的过程
我的python环境已经搭好了pip,可以用pip直接安装. 1.首先要安装基础环境: 1)yum install gcc glibc-devel zlib-devel rpm-build opens ...
- [目录] ASP.Net Core 搭建微服务网站
本项目采用ASP.Net Core微服务技术,搭建博客和Saas平台. 全文将围绕(1)设计模式 (2)敏捷开发 目的: 结构足够合理,代码足够优美,扩展性.可读性.易维护性做到最优. 以下目录仅为 ...
- Delphi - cxGrid添加Footer显示
cxGrid - 添加footer显示 1:添加Footer Items 单击cxGrid Customize... ,Summary,Add: 2:添加Footer items数据绑定 选中一条需要 ...
- mysql8.0版本下命令行mysqld –skip-grant-tables 失效,无法登陆的问题
1.管理员权限登陆cmd,不会使用管理员登陆的请搜索cmd,搜索结果右键. 2.命令行输入:net stop mysql;然后提示.服务停止中 --> 服务已停止,如出现其他错误请百度. 这只是 ...
- Python数据类型详解——列表
Python数据类型详解--列表 在"Python之基本数据类型概览"一节中,大概介绍了列表的基本用法,本节我们详细学一下列表. 如何定义列表:在[]内以英文里输入法的逗号,,按照 ...
- VMware虚拟机安装Linux系统详细教程
VMware14虚拟机安装RedHad6系统步骤 redhat网盘资源:链接:https://pan.baidu.com/s/1GlT20vevqbZ9qTxsGH1ZzA 提取码:oh57 如果网盘 ...
- 机器学习性能度量指标:ROC曲线、查准率、查全率、F1
错误率 在常见的具体机器学习算法模型中,一般都使用错误率来优化loss function来保证模型达到最优. \[错误率=\frac{分类错误的样本}{样本总数}\] \[error=\frac{1} ...
- JIRA中的核心概念
转载自:http://blog.csdn.net/zhengxy2011/article/details/6940380 1.1.1 问题 JIRA跟踪问题(Issue),这些问题可以是bug,功 ...
- 洛谷P1582 倒水 二进制 lowbit __builtin_popcount
P1582 倒水:https://www.luogu.org/problemnew/show/P1582 题意: 给定n瓶装有1升的水瓶,每次可以把两瓶装水量相同的水和成一瓶,问最少还要增加几瓶装有1 ...
- 用.NET写“算命”程序
用.NET写"算命"程序 "算命",是一种迷信,我父亲那一辈却执迷不悟,有时深陷其中,有时为求一"上上签",甚至不惜重金,向"天神 ...