当前位置: 首页 > news >正文

从零开始:Python语言进阶之迭代器

一、重新认识迭代与可迭代对象

 

1.1 什么是迭代

 

迭代是一种有序访问数据元素的方式,在Python编程中随处可见。最常见的迭代场景就是使用 for 循环,例如遍历列表中的元素:

fruits = ["apple", "banana", "cherry"]
for fruit in fruits:print(fruit)

在上述代码中, for 循环依次从 fruits 列表中取出每个元素,并将其赋值给 fruit 变量,这个过程就是迭代。本质上,迭代就是逐个处理数据集合中元素的过程,除了 for 循环,像 while 循环结合索引、列表推导式、生成器表达式等操作,底层也都依赖迭代机制。

 

1.2 可迭代对象(Iterable)

 

可迭代对象是Python中能够被迭代的数据结构。判断一个对象是否为可迭代对象,除了使用 isinstance() 函数结合 collections.abc.Iterable 模块外,还可以通过尝试调用对象的 __iter__() 方法来判断。如果对象有 __iter__() 方法,那么它就是可迭代对象。

from collections.abc import Iterable# 使用isinstance判断
my_str = "hello"
print(isinstance(my_str, Iterable))  # 输出: True# 通过尝试调用__iter__方法判断
try:iter(my_str)print("是可迭代对象")
except TypeError:print("不是可迭代对象")

Python中常见的可迭代对象包括:

 

① 序列类型:列表(list)、元组(tuple)、字符串(str)。列表是可变的有序集合,元组是不可变的有序集合,字符串则是字符的有序集合,它们都支持按顺序迭代。

my_list = [1, 2, 3]
my_tuple = (4, 5, 6)
my_str = "abc"for element in my_list:print(element)for element in my_tuple:print(element)for char in my_str:print(char)

② 映射类型:字典(dict)。字典迭代时默认遍历的是键(keys),也可以通过 values() 方法遍历值,通过 items() 方法同时遍历键值对。

my_dict = {"name": "Alice", "age": 25}
for key in my_dict:print(key)for value in my_dict.values():print(value)for key, value in my_dict.items():print(key, value)

③ 集合类型:集合(set)、冻结集合(frozenset)。集合是无序不重复元素的集合,在迭代时虽然顺序不确定,但依然可以逐个访问元素。

my_set = {1, 2, 3}
for element in my_set:print(element)

④ 文件对象:当打开一个文件后,文件对象也是可迭代的,可以逐行读取文件内容。

with open("test.txt", "r") as file:for line in file:print(line.strip())

二、迭代器的核心概念与实现

 

2.1 迭代器的定义

 

迭代器是Python中实现了 __iter__() 和 __next__() 方法的对象。 __iter__() 方法必须返回迭代器自身,它的主要作用是在需要时将迭代器对象传递出去; __next__() 方法用于获取下一个元素,当没有更多元素可供返回时,必须引发 StopIteration 异常,以此来告知迭代过程结束。

 

2.2 迭代器的工作机制

 

以一个简单的自定义迭代器类为例,深入剖析迭代器的工作流程:

class CounterIterator:def __init__(self, stop):self.current = 0self.stop = stopdef __iter__(self):return selfdef __next__(self):if self.current >= self.stop:raise StopIterationresult = self.currentself.current += 1return result

当我们使用 for 循环遍历这个迭代器时:

 

1. 首先执行 iter(counter) ,即调用 CounterIterator 类的 __iter__() 方法,由于 __iter__() 方法返回的是迭代器 自身( return self ),所以获取到了迭代器对象。

counter = CounterIterator(5)
iterator_obj = iter(counter)

2. 然后 for 循环不断调用 next(iterator_obj) ,也就是调用迭代器对象的 __next__() 方法。在 __next__() 方法中,先检查 self.current 是否达到了停止条件( self.current >= self.stop ),如果没有达到,就将当前的 self.current 值赋值给 result ,然后将 self.current 自增1,最后返回 result 。

print(next(iterator_obj))  # 输出 0
print(next(iterator_obj))  # 输出 1

3. 当 self.current 达到停止条件时, __next__() 方法引发 StopIteration 异常, for 循环检测到这个异常后,会自动结束循环。

# 连续调用next,最后会引发StopIteration异常
try:for _ in range(6):print(next(iterator_obj))
except StopIteration:print("迭代结束")

三、Python内置迭代器工具详解

 

3.1  iter() 函数

 

 iter() 函数是将可迭代对象转换为迭代器对象的关键工具。它有两种使用形式:

 

① 基本形式:直接传入可迭代对象,返回对应的迭代器。

my_list = [10, 20, 30]
list_iterator = iter(my_list)
print(next(list_iterator))  # 输出: 10

② 带哨兵值的形式: iter(callable, sentinel) ,这种形式会不断调用 callable 对象,直到返回值等于 sentinel 时停止迭代。常用于从文件中读取数据,直到遇到特定的结束标识。

def get_number():num = 1while True:yield numnum += 1number_generator = get_number()
# 迭代直到数字等于5
for element in iter(lambda: next(number_generator), 5):print(element)

3.2  next() 函数

 

 next() 函数用于调用迭代器的 __next__() 方法,获取迭代器的下一个元素。它还可以接受第二个参数,作为默认返回值。当迭代器耗尽,且指定了默认返回值时, next() 函数不会引发 StopIteration 异常,而是返回默认值。

my_list = [1, 2, 3]
my_iter = iter(my_list)
print(next(my_iter))  # 输出: 1
print(next(my_iter))  # 输出: 2
print(next(my_iter))  # 输出: 3
# 迭代器耗尽后,指定默认返回值
print(next(my_iter, "迭代结束"))  # 输出: 迭代结束

3.3 生成器(Generator)

 

生成器是一种语法糖形式的迭代器,使用更加简洁。它通过在函数中使用 yield 关键字来实现。当生成器函数被调用时,不会立即执行函数体,而是返回一个生成器对象。每次调用 next() 方法(或使用 for 循环迭代)时,函数从上次 yield 语句暂停的位置继续执行,直到遇到下一个 yield 语句或函数结束。

def even_numbers_generator():num = 0while True:yield numnum += 2even_gen = even_numbers_generator()
print(next(even_gen))  # 输出: 0
print(next(even_gen))  # 输出: 2

此外,还有生成器表达式,它的语法和列表推导式类似,只是将方括号 [] 换成圆括号 () 。生成器表达式也是返回一个生成器对象,具有延迟计算的特性,相比列表推导式更节省内存。

squared_generator = (x ** 2 for x in range(5))
for num in squared_generator:print(num)

四、基础应用场景与常见问题解析

 

4.1 基础应用场景

 

① 文件逐行处理:在处理大文件时,使用迭代器逐行读取文件内容,避免一次性将整个文件读入内存。

with open("large_file.txt", "r") as file:for line in file:# 对每一行进行处理,例如统计行数、查找特定字符串等pass

② 自定义数据遍历:通过自定义迭代器类,实现对自定义数据结构的遍历。比如自定义一个链表类,通过迭代器实现对链表节点的遍历。

class Node:def __init__(self, value):self.value = valueself.next = Noneclass LinkedList:def __init__(self):self.head = Nonedef add_node(self, value):new_node = Node(value)if not self.head:self.head = new_nodeelse:current = self.headwhile current.next:current = current.nextcurrent.next = new_nodedef __iter__(self):current = self.headwhile current:yield current.valuecurrent = current.nextlinked_list = LinkedList()
linked_list.add_node(1)
linked_list.add_node(2)
linked_list.add_node(3)for element in linked_list:print(element)

4.2 常见问题与解决
 
① 迭代器重复使用问题:迭代器是一次性的,一旦迭代结束就无法再次迭代。如果需要重复迭代,必须重新创建迭代器对象。

my_list = [1, 2, 3]
my_iter = iter(my_list)
for element in my_iter:print(element)
# 此时my_iter已耗尽,再次迭代无输出
for element in my_iter:print(element)# 重新创建迭代器对象即可再次迭代
new_iter = iter(my_list)
for element in new_iter:print(element)

② 迭代器与循环终止条件:在使用 while 循环结合 next() 函数手动迭代时,需要正确处理 StopIteration 异常来控制循环终止。

my_list = [1, 2, 3]
my_iter = iter(my_list)
while True:try:element = next(my_iter)print(element)except StopIteration:break

深入理解迭代器的基础概念与原理,是掌握Python进阶编程的重要一步。从可迭代对象到迭代器的转换,再到各种内置工具的使用,以及实际应用中的问题处理,这些基础知识构成了灵活运用迭代器的基石。通过不断实践,能够更加熟练地使用迭代器优化代码,提升程序的性能与可读性。

我是玉笥寻珍,正在持续更新中,感谢您的关注

相关文章:

  • NotePad++编辑Linux服务器文档
  • uni-app学习笔记十--vu3 computed的运用(二)
  • 图论核心:深度搜索DFS 与广度搜索BFS
  • <uniapp><threejs>在uniapp中,怎么使用threejs来显示3D图形?
  • 无心剑中译戴维斯《悠闲》
  • uni-app学习笔记十四-vue3中emit的使用
  • rabbitmq的使用介绍
  • 【TDengine源码阅读】举例说明pthread_once_t和PTHREAD_ONCE_INIT
  • PPT连同备注页(演讲者模式)一块转为PDF
  • 深入浅出IIC协议 - 从总线原理到FPGA实战开发 -- 第六篇:AXI4-Lite桥接设计
  • 鸿蒙仓颉开发语言实战教程:页面跳转和传参
  • Java多线程JUC
  • 2025.05.23 Axure 动态面板学习笔记
  • Linux 的编辑器--vim
  • Apache 高级配置实战:从连接保持到日志分析的完整指南
  • 对WireShark 中的UDP抓包数据进行解析
  • Php JIT 使用详解
  • 从智能提效到产品赋能的架构实践
  • 【HW系列】—web常规漏洞(SQL注入与XSS)
  • RocketMQ 5.0 核心概念与架构解析
  • 高端网站建设公司哪家公司好/室内设计培训
  • 手机壳图案设计网站/百度网址大全网站大全
  • 门户网站和新闻网站的区别/策划营销推广方案
  • 企业宣传网站建设需求说明书的模板/整合营销传播成功案例
  • 城乡建设管理局的网站/海会网络做的网站怎么做优化
  • 做网站找云无限/网络营销课程个人总结