Python 全栈:Python 应用迭代器和生成器的 9 个案例

列表和迭代器区别

有些读者朋友,区分不开列表、字典、集合等非迭代器对象与迭代器对象,觉得迭代器是多余的。

先探讨它们的区别。首先,创建一个列表 a:

a = [1,3,5,7]

有没有朋友认为,列表就是迭代器的?注意列表 a 可不是迭代器类型(Iterator)。要想成为迭代器,需要经过内置函数 iter 包装:

a_iter = iter(a)

此时 a_iter 就是 Iterator,迭代器。可以验证:

In [21]: from collections.abc import Iterator
    ...: isinstance(a_iter,Iterator)
Out[21]: True

分别遍历 a、a_iter:

In [22]: for i in a:
    ...:     print(i)
    ...:
1
3
5
7

In [23]: for i in a_iter:
    ...:     print(i)
    ...:
1
3
5
7

打印结果一样,但是,再次遍历 a、a_iter 就会不同,a 正常打印,a_iter 没有打印出任何信息:

In [24]: for i in a:
    ...:     print(i)
    ...:
1
3
5
7

In [25]: for i in a_iter:
    ...:     print(i)
    ...:

这就是列表 a 和迭代器 a_iter 的区别:

列表不论遍历多少次,表头位置始终是第一个元素;
迭代器遍历结束后,不再指向原来的表头位置,而是为最后元素的下一个位置。
只有迭代器对象才能与内置函数 next 结合使用,next 一次,迭代器就前进一次,指向一个新的元素。

所以,要想迭代器 a_iter 重新指向 a 的表头,需要重新创建一个新的迭代 a_iter_copy

In [27]: a_iter_copy = iter(a)

调用 next,输出迭代器指向 a 的第一个元素:

In [28]: next(a_iter_copy)
Out[28]: 1

值得注意,我们无法通过调用 len 获得迭代器的长度,只能迭代到最后一个末尾元素时,才知道其长度。

那么,怎么知道迭代到元素末尾呢?我们不妨一直 next,看看会发生什么:

In [30]: next(a_iter_copy)
Out[30]: 3

In [31]: next(a_iter_copy)
Out[31]: 5

In [32]: next(a_iter_copy)
Out[32]: 7

In [33]: next(a_iter_copy)

StopIteration:
等迭代到最后一个元素后,再执行 next,会触发 StopIteration 异常。

所以,通过捕获此异常,就能求出迭代器指向 a 的长度,如下:

a = [1, 3, 5, 7]
a_iter_copy2 = iter(a)
iter_len = 0
try:
    while True:
        i = next(a_iter_copy2)
        print(i)
        iter_len += 1
except StopIteration:
    print('iterator stops')

print('length of iterator is %d' % (iter_len,))

打印结果:

1
3
5
7
iterator stops
length of iterator is 4

以上总结:遍历列表,表头位置始终不变;遍历迭代器,表头位置相应改变;next 函数执行一次,迭代对象指向就前进一次;StopIteration 触发时,意味着已到迭代器尾部。

认识到迭代器和列表等区别后,我们再来说说生成器。

yield 的函数是生成器,而生成器也是一种迭代器。所以,生成器也有上面那些迭代器的特点。前些天已经讨论过生成器的一些基本知识,今天主要讨论生成器带来哪些好处,实际的使用场景在哪里。

节省内存案例

求一组数据累积乘,比如:三个数 [1,2,3],累积乘后返回 [1,2,6]。

一般的方法:

还有 79% 的精彩内容
©著作权归作者所有,转载或内容合作请联系作者
支付 ¥2.99 继续阅读
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,657评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,889评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,057评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,509评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,562评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,443评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,251评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,129评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,561评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,779评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,902评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,621评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,220评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,838评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,971评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,025评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,843评论 2 354