迭代器跟生成器,与上篇文章讲的装饰器一样,都是属于我的一个老大难问题。

通常就是遇到的时候就去搜一下,结果在一大坨各种介绍博客中看了看,回头又忘记了。

你是不是也是这样呢?

俗话说:好记性不如烂笔头,虽然现在基本不咋用笔写字了,但是还是要好好整理下,起码以后我就不用搜了。

如果现在给你一个列表list_a = [1, 2, 3, 4],让你去迭代它,相信大家都很熟悉,直接用for循环就完事儿,

list_a = [1, 2, 3, 4]

for i in list_a:
print(i)

运行

1
2
3
4
[Finished in 0.1s]

可以看到,for循环迭代了列表中的每一个元素,打印了出来。

那么for循环背后都做了什么事情呢?

一、 容器、可迭代对象、迭代器

听起来陌生,但是你绝对熟悉的词儿。

在python中,一切都是对象,对象的抽象是类,而对象的集合就是容器。

使用python中常见的容器有很多,比如:列表list:[0, 1, 2]集合set:([0, 1, 2])字典dict:{0:0, 1:1, 2:2}以及元组tuple(0, 1, 2)

这些都是多个元素集中在一起的单元,区别的是内部数据结构的实现方法。

所有的容器都是可以迭代的,你可以用for循环去迭代上述的容器试试。

那把一个个元素找出来,用到的就是迭代器。用iter()可以创建一个迭代器。

迭代器提供一个next()方法,这个方法你每次调用的时候会给你返回下一个对象,或者StopIteration,也就是没有对象可以给你了。

list_a = [1, 2, 3, 4]

it = iter(list_a) # 创建迭代器

print(next(it)) #调用next()
print(next(it))
print(next(it))
print(next(it))
print(next(it))

运行结果,前4个print可以正常返回,第5个时候就出现StopIteration错误了,因为列表中4个元素已经返回完了。

1
2
3
4
Traceback (most recent call last):
File "D:\练习\demo_iterator.py", line 9, in <module>
print(next(it))
StopIteration
[Finished in 0.1s with exit code 1]

二、生成器

什么是生成器?简单粗暴一点:生成器就是懒人版的迭代器。

在上述的创建迭代器操作中,我们显然是做了一次性生成的操作,list_a = [1, 2, 3, 4],这4个元素一次性生成好,以供next()调用。

但是生成出的这些元素都是会保存到内存中去,这只是4个元素,如果有上千万、上亿元素呢?

我并不是第一时间要用到所有的元素,我只要在我调用next()的时候产生一个返回给我就好,那么这样一次性生成就会白白占用了大量的内存。

生成器应运而生,当调用next()的时候,才会生成下一个变量。

生成器的写法很简单,用小括号,比如把一个列表生成式括起来:(i for i in range(10000)),这样就初始化了一个生成器。

print([i for i in range(10)])

print(i for i in range(10))

上面的时列表,下面的就是一个生成器了,区别就是[]()

运行结果:

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
<generator object <genexpr> at 0x033383A8>
[Finished in 0.1s]

yield关键字

此外,函数也可以成为生成器,秘密就是yield关键字,比如:

def gen():
a = 0
while a < 100:
yield a
a += 1 test = gen()
print(next(test))
print(next(test))
print(next(test))
print(next(test))

运行结果:

0
1
2
3
[Finished in 0.1s]

yield关键字,可以这样理解:当函数运行到这一行的时候,程序会从这里暂停,yield相当于return会返回,

当下次迭代时候,则会从yield的下一行代码开始执行。

所以,我调用了4次print,可以从0开始依次输出。

从我工作中的使用场景出发的话,我在做一些自动化测试的时候,有些变量参数是不可以重复的,用迭代器来定义变量的生成规则,每次

调用都会产生一个新的,就不会重复了。

【python】迭代器与生成器到底是什么?看完你就知道的更多相关文章

  1. 一文搞懂Python迭代器和生成器

    很多童鞋搞不懂python迭代器和生成器到底是什么?它们之间又有什么样的关系? 这篇文章就是要用最简单的方式让你理解Python迭代器和生成器! 1.迭代器和迭代过程 维基百科解释道: 在Python ...

  2. Python 迭代器和生成器(转)

    Python 迭代器和生成器 在Python中,很多对象都是可以通过for语句来直接遍历的,例如list.string.dict等等,这些对象都可以被称为可迭代对象.至于说哪些对象是可以被迭代访问的, ...

  3. Python - 迭代器与生成器 - 第十三天

    Python 迭代器与生成器 迭代器 迭代是Python最强大的功能之一,是访问集合元素的一种方式. 迭代器是一个可以记住遍历的位置的对象. 迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问 ...

  4. 怎么理解Python迭代器与生成器?

    怎么理解Python迭代器与生成器?在Python中,使用for ... in ... 可以对list.tuple.set和dict数据类型进行迭代,可以把所有数据都过滤出来.如下:         ...

  5. Python迭代器,生成器--精华中的精华

    1. 迭代器 迭代器是访问集合元素的一种方式.迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退.另外,迭代器的一大 ...

  6. python迭代器,生成器

    1. 迭代器 迭代器是访问集合元素的一种方式.迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退.另外,迭代器的一大 ...

  7. python -迭代器与生成器 以及 iterable(可迭代对象)、yield语句

    我刚开始学习编程没多久,对于很多知识还完全不知道,而有些知道的也是一知半解,我想把学习到的知识记录下来,一是弥补记忆力差的毛病,二也是为了待以后知识能进一步理解透彻时再回来做一个补充. 参考链接: 完 ...

  8. Python迭代器和生成器你学会了吗?

    在了解什么是迭代器和生成器之前,我们先来了解一下容器的概念.对于一切皆对象来说,容器就是对象的集合.例如列表.元祖.字典等等都是容器.对于容器,你可以很直观地想象成多个元素在一起的单元:而不同容器的区 ...

  9. python迭代器与生成器详解

    迭代器与生成器 迭代器(iterator)与生成器(generator)是 Python 中比较常用又很容易混淆的两个概念,今天就把它们梳理一遍,并举一些常用的例子. for 语句与可迭代对象(ite ...

随机推荐

  1. 自身写Android组合多个布局的经历

    今天不总结课程了,留着有时间补上. 今天的是ExpandListView,就是可以扩展的列表视图. 今天我做了个总结,然后模仿了扣扣的聊天界面,仅仅写了三个页面而已,用到的xml和活动就不下于10个, ...

  2. BiMPM:Bilateral Multi-Perspctive Matching for Natural Language Sentences

    导言 本论文的工作主要是在 'matching-aggregation'的sentence matching的框架下,通过增加模型的特征(实现P与Q的双向匹配和多视角匹配),来增加NLSM(Natur ...

  3. 在centos 上安装python

    1.下载最新版本python源码包 下载地址为https://www.python.org/ftp/python/3.8.5/Python-3.8.5.tgz 2.解压源码包 tar -zxf Pyt ...

  4. Nginx定时日志切割

    Nginx定时日志切割 现有的日志都会存在access.log文件中,但是随着时间的推移,这个文件的内容会越来越多,体积会越来越大,不便于运维 人员查看,所以我们可以通过把这个大的日志文件切割为多份不 ...

  5. android studio实现圆角的button

    操作过程 1. 在drawable中新建一个button_circle_shape.xml 但是建立这个xml是有操作的,因为从drawable右键是创建不了xml的, 具体操作如下: 右键res–& ...

  6. CF 1383B GameGame

    传送门 题目:给定长度为n的数组a,A和B轮流拿走一个数,开始时A和B拥有的v为0,A和B每次拿走一个数时,他的v = v^ ai,A和B都很聪明,问都按照最优的情况考虑,拿完所有数之后A和B的v的大 ...

  7. Mybatis中<![cdata[ ]]>

    1.<![cdata[ ]]>介绍 <![cdata[ 内容 ]]>是一种xml语法,在CDATA标记中的信息被解析器原封不动地传给应用程序,并且不解析该段信息中的任何控制标记 ...

  8. 解析Class文件之创建InstanceKlass对象

    ClassFileParser::parseClassFile()方法会将解析Class文件的大部分结果保存到instanceKlass对象中.创建instanceKlass对象的代码如下: int ...

  9. 什么情况下适合用UDP协议,什么情况下适合用TCP协议?

    总的来说 TCP协议提供可靠的服务, UDP协议提供高效率的服务. 高可靠性的TCP服务提供面向连接的服务,主要用于一次传输大量报文的情形, 如文件传输,远程登录等: 高效率的UDP协议提供无连接的数 ...

  10. java多线程之消费生产模型

    需求:要求仓库最大容量为4,且一共只生产20台电视机,下面的代码只适用于一个生产者一个消费者,有没有大佬提点建议怎么改成一对多或多对多不会出现死锁情况 class Warehouse { privat ...