news 2026/1/1 7:13:40

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
一文搞懂Python迭代器和生成器

很多童鞋搞不懂python迭代器和生成器到底是什么?它们之间又有什么样的关系?

这篇文章就是要用最简单的方式让你理解Python迭代器和生成器!

迭代器和迭代过程

维基百科解释道:

在Python中,迭代器是遵循迭代协议的对象。使用iter()从任何序列对象中得到迭代器(如list, tuple, dictionary, set等)。另一种形式的输入迭代器是generator(生成器)。

很多容器诸如列表、字符串可以用for循环遍历对象。

for语句会调用容器对象中的iter()函数, 该函数返回一个定义了__next__()方法的迭代器对象,该方法将逐一访问容器中的元素。

所以说:

python中,任意对象,只要定义了__next__方法,它就是一个迭代器。

因此,python中的容器如列表、元组、字典、集合、字符串都可以被称作迭代器。

讲完迭代器后,迭代就比较好理解了,迭代就是从迭代器中取元素的过程

比如我们用for循环从列表[1,2,3]中取元素,这种遍历过程就被称作迭代

# 列表是迭代器for element in [1, 2, 3]:print(element)# 元组是迭代器for element in (1, 2, 3):print(element)# 字典是迭代器for key in {'one':1, 'two':2}:print(key)# 字符串是迭代器for char in "123":print(char)# 打开的text同样是迭代器for line in open("myfile.txt"):print(line, end='')

如果你不想用for循环迭代呢?

这时你可以:

  1. 先调用容器(以字符串为例)的iter()函数

  2. 再使用next()内置函数来调用__next__()方法

  3. 当元素用尽时,__next__()将引发 StopIteration 异常

>>> s = 'abc'>>> it = iter(s)>>> it<iterator object at 0x00A1DB50>>>> next(it)'a'>>> next(it)'b'>>> next(it)'c'>>> next(it)Traceback (most recent call last):File "<stdin>", line 1, in <module>next(it)StopIteration

生成器 Generator

看看廖雪峰大神的解释:

通过列表生成式,我们可以直接创建一个列表。

但是,受到内存限制,列表容量肯定是有限的。

而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。

所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?

这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器(Generator)。

生成器也是一种迭代器,但是你只能对其迭代一次。

这是因为它们并没有把所有的值存在内存中,而是在运行时生成值

你通过遍历来使用它们,要么用一个for循环,要么将它们传递给任意可以进行迭代的函数和结构。

大多数时候生成器是以函数来实现的。然而,它们并不返回一个值,而是yield(暂且译作“生出”)一个值。

每次对生成器调用next()时,它会从上次离开位置恢复执行(它会记住上次执行语句时的所有数据值)。显示如何非常容易地创建生成器的示例如下:

def reverse(data):for index in range(len(data)-1, -1, -1):yield data[index]

    >>> for char in reverse('golf'):... print(char)...flog

    可以用生成器来完成的操作同样可以用前一节所描述的基于类的迭代器来完成。但生成器的写法更为紧凑,因为它会自动建__iter__()__next__()方法。

    生成器表达式

    生成器不一定要用复杂的函数表示,python提供了简洁的生成器表达式。

    从形式上来看,生成器表达式和列表推导式很像,仅仅是将列表推导式中的[]替换为(),但是两者差别挺大,生成器表达式可以说组合了迭代功能和列表解析功能。

    生成器表达式可以认为是一种特殊的生成器函数,类似于lambda表达式和普通函数。但是和生成器一样,生成器表达式也是返回生成器generator对象,一次只返回一个值

    >>> sum(i*i for i in range(10)) # sum of squares285
    >>> xvec = [10, 20, 30]>>> yvec = [7, 5, 3]>>> sum(x*y for x,y in zip(xvec, yvec)) # dot product260
    >>> from math import pi, sin>>> sine_table = {x: sin(x*pi/180) for x in range(0, 91)}
    >>> unique_words = set(word for line in page for word in line.split())
    >>> valedictorian = max((student.gpa, student.name) for student in graduates)
    >>> data = 'golf'>>> list(data[i] for i in range(len(data)-1, -1, -1))['f', 'l', 'o', 'g']

    版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
    网站建设 2025/12/23 5:30:43

    Vue虚拟滚动列表终极指南:告别大数据量卡顿的完整解决方案

    Vue虚拟滚动列表终极指南&#xff1a;告别大数据量卡顿的完整解决方案 【免费下载链接】vue-virtual-scroll-list ⚡️A vue component support big amount data list with high render performance and efficient. 项目地址: https://gitcode.com/gh_mirrors/vu/vue-virtual…

    作者头像 李华
    网站建设 2025/12/27 14:52:21

    传统VS现代:乱码生成效率提升10倍的方法

    快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 构建一个高效的乱码生成API服务&#xff0c;要求&#xff1a;1.支持RESTful接口 2.能处理高并发请求 3.提供多种乱码生成算法 4.有请求频率限制 5.返回JSON格式结果。使用Go语言开发…

    作者头像 李华
    网站建设 2025/12/27 8:07:09

    PHP+OpenSSL实现银行级支付加密(实战代码+性能优化策略)

    第一章&#xff1a;银行级支付加密的背景与PHP技术选型 在金融系统日益数字化的今天&#xff0c;支付安全成为银行与第三方支付平台的核心关注点。数据泄露、中间人攻击和身份伪造等风险促使企业必须采用银行级加密标准&#xff0c;如TLS 1.3、AES-256-GCM 和 RSA-OAEP&#xf…

    作者头像 李华
    网站建设 2025/12/31 13:13:10

    Docker + AI模型版本管理实战(从入门到生产落地的7个阶段)

    第一章&#xff1a;Docker 的 AI 模型版本管理方案在 AI 模型开发与部署过程中&#xff0c;模型版本的一致性、可复现性和环境隔离是关键挑战。Docker 提供了一种轻量级的容器化解决方案&#xff0c;通过将模型、依赖库、运行时环境打包为镜像&#xff0c;实现跨平台的一致性部…

    作者头像 李华
    网站建设 2025/12/23 16:20:35

    Zephyr 的 Counter alarm

    Zephyr 的 Counter 驱动支持“相对闹钟”和“绝对闹钟”两种触发语义。区别在于 struct counter_alarm_cfg 里的 flags 和 ticks 的含义。 关键结构体&#xff1a; struct counter_alarm_cfg {counter_alarm_callback_t callback; //回调uint32_t ticks; //不同模式下含义不同…

    作者头像 李华