news 2026/5/11 14:15:47

python易混淆知识点(十五)迭代器

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
python易混淆知识点(十五)迭代器

迭代器

  • 一、内置类型转换为迭代器
    • 1. 列表 (List) → 迭代器
    • 2. 元组 (Tuple) → 迭代器
    • 3. 字典 (Dict) → 迭代器
    • 4. 字符串 (String) → 迭代器
    • 5. 集合 (Set) → 迭代器
    • 转换为迭代器的不同方法对比
    • 完整示例:各种数据类型的迭代
    • 实际应用:数据处理
      • 场景1:批量处理数据
      • 场景2:链式迭代多个数据集
      • 场景3:创建自定义迭代器
    • 重要注意事项
  • 二、直接定义迭代器的3种方法
    • 方法1:使用 生成器函数(最常用)
    • 方法2:使用 生成器表达式(简洁版)
      • 方法3:创建 迭代器类(最灵活)
  • 三、迭代器的内存优势
      • 对比:列表 vs 生成器
  • 四、高级迭代器技巧
    • 1. `itertools` 模块(标准库中的迭代器工具)
    • 2. `yield from` 语法
  • 五、如何选择合适的迭代器定义方式
  • 六、总结

Python 中不仅可以转换基本类型为迭代器,还可以直接定义自定义的迭代器。 这是 Python 非常强大的特性。

一、内置类型转换为迭代器

1. 列表 (List) → 迭代器

my_list=[1,2,3,4,5]list_iter=iter(my_list)print(next(list_iter))# 输出: 1print(next(list_iter))# 输出: 2print(next(list_iter))# 输出: 3# 也可以用 for 循环foriteminlist_iter:# 从第4个元素开始print(item)# 输出: 4, 5

2. 元组 (Tuple) → 迭代器

my_tuple=('apple','banana','cherry')tuple_iter=iter(my_tuple)print(next(tuple_iter))# 'apple'print(next(tuple_iter))# 'banana'# 转换为列表查看剩余print(list(tuple_iter))# ['cherry']

3. 字典 (Dict) → 迭代器

字典有多种迭代方式:

my_dict={'name':'Alice','age':25,'city':'Beijing'}# 方法1:默认迭代键(keys)dict_iter_keys=iter(my_dict)print(next(dict_iter_keys))# 'name'(Python 3.7+ 保持插入顺序)print(next(dict_iter_keys))# 'age'# 方法2:明确迭代键dict_iter=iter(my_dict.keys())print(next(dict_iter))# 'name'# 方法3:迭代值dict_iter_values=iter(my_dict.values())print(next(dict_iter_values))# 'Alice'# 方法4:迭代键值对dict_iter_items=iter(my_dict.items())print(next(dict_iter_items))# ('name', 'Alice')

4. 字符串 (String) → 迭代器

字符串也可以迭代:

my_string="Hello"str_iter=iter(my_string)print(next(str_iter))# 'H'print(next(str_iter))# 'e'print(''.join(str_iter))# 'llo'

5. 集合 (Set) → 迭代器

my_set={1,3,5,7,9}set_iter=iter(my_set)print(next(set_iter))# 1(集合无序,顺序不确定)print(next(set_iter))# 3

转换为迭代器的不同方法对比

数据类型创建迭代器方法迭代内容示例
列表iter(lst)列表元素[1, 2, 3]1, 2, 3
元组iter(tup)元组元素('a', 'b')'a', 'b'
字典iter(dict)字典的键{'a':1}'a'
字典键iter(dict.keys())字典的键{'a':1}'a'
字典值iter(dict.values())字典的值{'a':1}1
字典项iter(dict.items())(键, 值)对{'a':1}('a', 1)
字符串iter(string)单个字符"hi"'h', 'i'
集合iter(set)集合元素{1, 2}1, 2(顺序不定)

完整示例:各种数据类型的迭代

# 定义各种数据结构my_list=[10,20,30]my_tuple=('x','y','z')my_dict={'a':1,'b':2,'c':3}my_string="Python"my_set={100,200,300}defiterate_data(data,data_type):"""通用迭代函数"""print(f"\n迭代{data_type}:")iterator=iter(data)try:foriinrange(5):# 最多尝试5次print(f" 第{i+1}次next():{next(iterator)}")exceptStopIteration:print(" 迭代结束")# 测试各种类型iterate_data(my_list,"列表")iterate_data(my_tuple,"元组")iterate_data(my_dict,"字典(默认迭代键)")iterate_data(my_dict.values(),"字典的值")iterate_data(my_string,"字符串")iterate_data(my_set,"集合")

实际应用:数据处理

场景1:批量处理数据

# 有一个数据列表,需要分批处理data_list=list(range(100))# 0-99data_iter=iter(data_list)batch_size=10batch_num=0whileTrue:batch=[]try:for_inrange(batch_size):batch.append(next(data_iter))exceptStopIteration:ifbatch:# 处理最后一批print(f"批次{batch_num}:{batch}")breakprint(f"批次{batch_num}:{batch}")batch_num+=1

场景2:链式迭代多个数据集

# 合并多个数据源的迭代器defchain_iterators(*iterables):"""链式迭代多个可迭代对象"""foriterableiniterables:yieldfromiterable# 使用list_data=[1,2,3]tuple_data=(4,5,6)dict_keys={'a':1,'b':2}.keys()combined_iter=chain_iterators(list_data,tuple_data,dict_keys)print(list(combined_iter))# [1, 2, 3, 4, 5, 6, 'a', 'b']

场景3:创建自定义迭代器

classDataLoader:"""模拟PyTorch DataLoader的简单版本"""def__init__(self,data,batch_size=2):self.data=data self.batch_size=batch_sizedef__iter__(self):self.index=0returnselfdef__next__(self):ifself.index>=len(self.data):raiseStopIteration batch=self.data[self.index:self.index+self.batch_size]self.index+=self.batch_sizereturnbatch# 使用自定义迭代器loader=DataLoader([1,2,3,4,5,6],batch_size=2)forbatchinloader:print(f"批次:{batch}")# 输出:# 批次: [1, 2]# 批次: [3, 4]# 批次: [5, 6]

重要注意事项

  1. 迭代器只能前进不能后退

    data=[1,2,3,4]it=iter(data)print(next(it))# 1print(next(it))# 2# 无法回到1
  2. 迭代器会消耗数据

    it=iter([1,2,3])list(it)# [1, 2, 3]list(it)# [],已经耗尽
  3. 可迭代对象 vs 迭代器

    lst=[1,2,3]# 可迭代对象it=iter(lst)# 迭代器# 可迭代对象可以多次创建迭代器it1=iter(lst)it2=iter(lst)
  4. 判断是否为迭代器

    fromcollections.abcimportIterator lst=[1,2,3]it=iter(lst)print(isinstance(lst,Iterator))# Falseprint(isinstance(it,Iterator))# True

二、直接定义迭代器的3种方法

方法1:使用 生成器函数(最常用)

defmy_generator(start,end):"""生成从 start 到 end 的整数"""current=startwhilecurrent<=end:yieldcurrent# yield 是关键!current+=1# 使用gen=my_generator(1,5)# 这已经是一个迭代器print(type(gen))# <class 'generator'>print(next(gen))# 1print(next(gen))# 2print(list(gen))# [3, 4, 5](剩余的部分)

方法2:使用 生成器表达式(简洁版)

# 类似列表推导式,但用圆括号gen_expr=(x**2forxinrange(5))# 生成器表达式print(type(gen_expr))# <class 'generator'>print(next(gen_expr))# 0print(next(gen_expr))# 1print(list(gen_expr))# [4, 9, 16]

方法3:创建 迭代器类(最灵活)

classMyIterator:"""自定义迭代器类"""def__init__(self,start,end):self.current=start self.end=enddef__iter__(self):"""返回迭代器自身"""returnselfdef__next__(self):"""返回下一个值"""ifself.current>self.end:raiseStopIterationelse:value=self.current self.current+=1returnvalue# 使用my_iter=MyIterator(1,3)print(type(my_iter))# <class '__main__.MyIterator'>print(next(my_iter))# 1print(next(my_iter))# 2print(next(my_iter))# 3print(next(my_iter))# 抛出 StopIteration

三、迭代器的内存优势

对比:列表 vs 生成器

importsys# 方法1:使用列表(占用大量内存)defget_numbers_list(n):"""返回包含前n个数字的列表"""numbers=[]foriinrange(n):numbers.append(i)returnnumbers# 方法2:使用生成器(节省内存)defget_numbers_generator(n):"""生成前n个数字"""foriinrange(n):yieldi# 对比内存使用n=1000000# 列表:一次性在内存中创建所有元素list_numbers=get_numbers_list(n)print(f"列表占用内存:{sys.getsizeof(list_numbers)}字节")# 约 8MB# 生成器:一次只生成一个元素gen_numbers=get_numbers_generator(n)print(f"生成器占用内存:{sys.getsizeof(gen_numbers)}字节")# 约 100 字节# 但只能使用一次print(sum(gen_numbers))# 正常工作print(sum(gen_numbers))# 0(生成器已耗尽)

四、高级迭代器技巧

1.itertools模块(标准库中的迭代器工具)

importitertools# 无限迭代器counter=itertools.count(start=10,step=2)print(next(counter))# 10print(next(counter))# 12print(next(counter))# 14# 循环迭代器cycle_iter=itertools.cycle(['A','B','C'])print(next(cycle_iter))# Aprint(next(cycle_iter))# Bprint(next(cycle_iter))# Cprint(next(cycle_iter))# A(又回到开头)# 排列组合permutations=itertools.permutations([1,2,3],2)print(list(permutations))# [(1,2), (1,3), (2,1), (2,3), (3,1), (3,2)]

2.yield from语法

defchain_generators(*iterables):"""连接多个生成器"""foritiniterables:yieldfromit# 委托给子生成器# 使用result=chain_generators([1,2,3],(4,5,6),{7,8,9})print(list(result))# [1, 2, 3, 4, 5, 6, 8, 9, 7](集合顺序不确定)

五、如何选择合适的迭代器定义方式

场景推荐方式示例
简单序列生成生成器表达式(x**2 for x in range(10))
复杂数据生成生成器函数def read_file(): yield line
需要状态维护迭代器类class DataLoader:
需要重复杂用可迭代对象实现__iter__()返回新迭代器
组合现有迭代器itertools模块itertools.chain()

六、总结

  • Python 可以直接定义迭代器,而不仅限于转换基本类型

  • 三种主要方法

    • 生成器函数(yield关键字)
    • 生成器表达式(圆括号推导式)
    • 迭代器类(实现__iter____next__
  • 在深度学习中,自定义迭代器非常有用,可以:

    • 实现自定义 DataLoader
    • 处理流式数据
    • 节省内存(特别是处理大数据时)
    • 实现复杂的数据预处理流
  • 所有可迭代对象都可以用iter()转换为迭代器

  • 列表、元组:迭代元素

  • 字典:默认迭代键,也可用.values().items()迭代值和键值对

  • 字符串:迭代字符

  • 集合:迭代元素(顺序不确定)

  • 迭代器是单向的、消耗性的,使用next()逐个获取元素

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

为什么顶级AI实验室都在抢用Open-AutoGLM沉思版?真相令人震惊

第一章&#xff1a;Open-AutoGLM沉思版 地址Open-AutoGLM 沉思版是一款基于 AutoGLM 架构优化的开源语言模型推理框架&#xff0c;专注于本地化部署与高效推理能力。该版本通过轻量化设计和动态计算图优化&#xff0c;在保持高精度的同时显著降低资源消耗&#xff0c;适用于边缘…

作者头像 李华
网站建设 2026/5/9 16:48:43

语音克隆技术演进:从Tacotron到GPT-SoVITS

语音克隆技术演进&#xff1a;从Tacotron到GPT-SoVITS 在内容创作日益个性化的今天&#xff0c;我们是否还能接受千篇一律的“机器音”&#xff1f;当虚拟主播需要复刻真人声线、视障用户希望听到亲人的声音朗读消息、有声书作者想用自己训练的音色演绎全本小说时&#xff0c;传…

作者头像 李华
网站建设 2026/5/9 16:09:29

PDF Craft:重新定义智能PDF转换体验的终极利器

PDF Craft&#xff1a;重新定义智能PDF转换体验的终极利器 【免费下载链接】pdf-craft PDF craft can convert PDF files into various other formats. This project will focus on processing PDF files of scanned books. The project has just started. 项目地址: https:/…

作者头像 李华
网站建设 2026/5/9 12:55:43

Bazzite 终极安装指南:打造专业级 Linux 游戏系统

Bazzite 终极安装指南&#xff1a;打造专业级 Linux 游戏系统 【免费下载链接】bazzite Bazzite is an OCI image that serves as an alternative operating system for the Steam Deck, and a ready-to-game SteamOS-like for desktop computers, living room home theater PC…

作者头像 李华
网站建设 2026/5/10 5:15:05

如何用AutoRaise彻底改变你的macOS多任务工作流:完整配置指南

如何用AutoRaise彻底改变你的macOS多任务工作流&#xff1a;完整配置指南 【免费下载链接】AutoRaise AutoRaise (and focus) a window when hovering over it with the mouse 项目地址: https://gitcode.com/gh_mirrors/au/AutoRaise AutoRaise是一款革命性的macOS开源…

作者头像 李华
网站建设 2026/5/10 19:32:59

11、利用 Git 钩子、别名和脚本提升日常工作效率

利用 Git 钩子、别名和脚本提升日常工作效率 在企业环境中,代码的产出需要满足一定的前提条件,比如代码要能编译通过、通过特定的单元测试集,并且提交信息中要有相关的文档说明,像引用 bug 修复 ID 或实例等。这些操作很多时候可以通过脚本来实现,将这些步骤融入到开发流…

作者头像 李华