python中的迭代器和生成器

1.迭代器

python的for循环就是通过迭代器来实现的,当我们使用for循环遍历一个容器时,python会自动创建一个迭代对象,并调用__next__()方法来获取容器中的下一个元素,直到容器中的所有元素都被遍历完毕。

除了使用for循环,还可以使用iter()函数来手动创建一个迭代器对象,并使用next()函数来获取容器中的下一个元素,这种方式可以让我们更灵活地控制迭代的过程。

当处理无法一次性加载到内存中的大文件、数据库记录或大规模数据结构时,迭代器可以逐条读取数据,无需全部加载,从而节省内存。

python 复制代码
# -*- coding: utf-8 -*-

data = [1, 3, 4, 5, 9]
it = iter(data)  # 迭代器,it 首先索引为 0

print(type(it))  # <class 'list_iterator'>
print(next(it))  # 1
print(next(it))  # 3
print(next(it))  # 4

# 查看迭代器中剩余的值
for item in it:
    print(item)  # 5 和 9
# 注意每次调用next就会减少减少迭代器中剩余的值

2.生成器

Python中一种特殊的迭代器,它是一个能按需生成值的轻量级对象。与一次性创建所有元素的数据结构(如列表或元组)不同,生成器在每次迭代时只生成下一个值,从而节省内存并支持无限序列或其他大量数据流的操作。可以用元组推导式或者yield关键字创建生成器。

用元组推导式创建生成器

python 复制代码
# -*- coding: utf-8 -*-

# data = [x for x in range(100000000)]
# 这种情况程序会运行很慢,占用内存很大

data = (x for x in range(100000000))
print(type(data))  # <class 'generator'> # 在循环时用来节约内存,
print(next(data))  # 0
print(next(data))  # 1
print(next(data))  # 2

使用 yield 的函数变成生成器(generator)

python 复制代码
def go1():
    print(100)
    print(200)
    print(300)


# 函数里面加 yield,变成生成器,分段执行
def go2():
    print(100)
    yield 1
    print(200)
    yield 2
    print(300)
    yield 5


# print(type(go1))   # <class 'function'>
# print(type(go1()))  # <class 'NoneType'>

# print(type(go2))  # <class 'function'>

gen = go2()
print(type(gen))  # <class 'generator'> # go2()是一个生成器

ret = next(gen)  # 执行语句"print(100)" 且返回值为 yield 后面设置的值 1
print(ret)  # 1

ret = next(gen)  # 执行语句"print(200)" 且返回值为 yield 后面设置的值 2
print(ret)  # 2

ret = next(gen)  # 执行语句"print(300)",且返回值为 yield 后面设置的值 5
print(ret)  # 5

# 注意,go2 函数不能直接调用,只能通过 next 来调用

# next(gen)  # 报错:StopIteration
try:
    next(gen)
except StopIteration:
    print("迭代结束")

访问生成器

python 复制代码
def go2():
    print(100)
    yield 1
    print(200)
    yield 2
    print(300)
    yield 5


gen = go2()
for item in gen:
    print(type(item))
    print(item)

"""
100
<class 'int'>
1
200
<class 'int'>
2
300
<class 'int'>
5

可以看到for循环遍历了生成器中的yield后面的那个值
"""

end

相关推荐
yangzhi_emo几秒前
ES6笔记2
开发语言·前端·javascript
emplace_back1 小时前
C# 集合表达式和展开运算符 (..) 详解
开发语言·windows·c#
jz_ddk1 小时前
[学习] C语言数学库函数背后的故事:`double erf(double x)`
c语言·开发语言·学习
萧曵 丶1 小时前
Rust 所有权系统:深入浅出指南
开发语言·后端·rust
xiaolang_8616_wjl1 小时前
c++文字游戏_闯关打怪2.0(开源)
开发语言·c++·开源
收破烂的小熊猫~1 小时前
《Java修仙传:从凡胎到码帝》第四章:设计模式破万法
java·开发语言·设计模式
蹦蹦跳跳真可爱5892 小时前
Python----OpenCV(图像増强——高通滤波(索贝尔算子、沙尔算子、拉普拉斯算子),图像浮雕与特效处理)
人工智能·python·opencv·计算机视觉
nananaij2 小时前
【Python进阶篇 面向对象程序设计(3) 继承】
开发语言·python·神经网络·pycharm
雷羿 LexChien2 小时前
从 Prompt 管理到人格稳定:探索 Cursor AI 编辑器如何赋能 Prompt 工程与人格风格设计(上)
人工智能·python·llm·编辑器·prompt