百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程网 > 正文

Python 迭代器与可迭代对象,还在傻傻分不清楚吗

yuyutoo 2025-03-24 22:21 4 浏览 0 评论

引言:迭代对象和迭代器到底是个啥

小白:专家,能给我讲讲 Python 里的迭代器和可迭代对象吗?感觉这两个概念有点模糊。

专家:当然可以。简单来说,可迭代对象就是能在 for 循环中使用的对象,像列表、元组、字典、字符串这些常见的数据类型都是可迭代对象。比如我们有一个列表:

my_list = [1, 2, 3, 4, 5]
for item in my_list:
	print(item)

在这段代码里,my_list就是一个可迭代对象,我们可以用for循环遍历它里面的每一个元素。

小白:那迭代器又是什么呢?

专家迭代器是一种特殊的对象它不仅是可迭代对象(实现了__iter__方法),还实现了__next__方法。__next__方法用于逐个返回元素,当没有更多元素时,会抛出StopIteration异常。迭代器有点像一个指针,每次调用__next__方法,它就会指向下一个元素。

比如,我们可以把刚才的列表转换成迭代器:

my_list = [1, 2, 3, 4, 5]
my_iter = iter(my_list)
print(next(my_iter)) # 输出1
print(next(my_iter)) # 输出2
print(next(my_iter)) # 输出3
print(next(my_iter)) # 输出4
print(next(my_iter)) # 输出5
# print(next(my_iter)) # 这行会抛出StopIteration异常

这里通过iter()函数把列表my_list转换成了迭代器my_iter,然后用next()函数不断获取迭代器中的下一个元素。但如果不是迭代器,使用next函数就会报错,比如:

next(my_list)

#会报错如下
Traceback (most recent call last):
File "test.py", line 9, in 
next(my_list)
TypeError: 'list' object is not an iterator

可迭代对象和迭代器有什么关系

小白:那可迭代对象和迭代器有什么关系呢?

专家所有的迭代器都是可迭代对象,但可迭代对象不一定是迭代器。就像我们上面看到的列表,它是可迭代对象,但不是迭代器。要判断一个对象是否是可迭代对象,可以使用isinstance函数结合Iterable类型来判断,判断是否是迭代器则用Iterator类型。

from typing import Iterable, Iterator
my_list = [1, 2, 3, 4, 5]
print(isinstance(my_list, Iterable)) # 输出True
print(isinstance(my_list, Iterator)) # 输出False
my_iter = iter(my_list)
print(isinstance(my_iter, Iterable)) # 输出True
print(isinstance(my_iter, Iterator)) # 输出True

闭坑指南:这里要注意,不要对非可迭代对象使用iter()函数,否则会报错。比如对一个整数使用iter():

iter(10) # 这行会报错,TypeError: 'int' object is not iterable

常见的可迭代对象

小白:明白了,那还有哪些常见的可迭代对象呢?

专家:除了列表,元组、字典、集合、字符串都是可迭代对象。例如:

# 元组
my_tuple = (1, 2, 3)
for item in my_tuple:
 	print(item)
# 字典
my_dict = {'a': 1, 'b': 2, 'c': 3}
for key, value in my_dict.items():
	print(key, value)
# 集合
my_set = {1, 2, 3}
for item in my_set:
	print(item)
# 字符串
my_str = "hello"
for char in my_str:
	print(char)

闭坑指南:在遍历字典时,如果在循环中修改字典的大小(比如添加或删除键值对),可能会导致不可预测的结果。所以尽量不要在遍历字典时修改它。

自定义迭代对象和迭代器

小白:那我们可以自己定义可迭代对象和迭代器吗?

专家:当然可以。要定义一个可迭代对象,我们需要在类中实现__iter__方法。如果要定义一个迭代器,除了__iter__方法,还需要实现__next__方法。

举例:传入一个数字,返回被2整除的大于0的数字。

class MyIterator():
	def __init__(self,digitnum):
		self.digitnum=digitnum
		self.current_num = 0
	def __iter__(self):
		print('调用了__iter__方法')
		return self
	def __next__(self):
		print('调用了__next__方法')
		while True:
			if self.current_num >= self.digitnum:
				raise StopIteration
			if self.current_num % 2 == 0 and self.current_num != 0:
				temp_num = self.current_num
				self.current_num += 1
				return temp_num
			self.current_num += 1

实例化后执行for循环

myiterator = MyIterator(11)
#for循环自定义的迭代器
for i in myiterator:
	print(i)
#结果如下:
调用了__iter__方法
调用了__next__方法
2
调用了__next__方法
4
调用了__next__方法
6
调用了__next__方法
8
调用了__next__方法
10
调用了__next__方法

这里MyIterator类实现了__iter__和__next__方法,所以它是一个迭代器。在for循环中使用它时,会自动调用__iter__方法获取迭代器对象,然后不断调用__next__方法获取下一个偶数,直到达到指定的限制。

闭坑指南:在实现__next__方法时,一定要注意在合适的时候抛出StopIteration异常,否则循环不会停止,可能导致程序陷入死循环。

生成器也是一种迭代器

小白:听说生成器和迭代器也有关系,能讲讲吗?

专家:没错,生成器其实是一种特殊的迭代器。有两种方式创建生成器,一种是使用生成器表达式,另一种是在函数中使用yield关键字。

1)我们用生成器表达式创建一个生成器,它能生成 1 到 10 之间的偶数:

my_generator = (i for i in range(1, 11) if i % 2 == 0)
print(isinstance(my_generator, Iterable)) # 输出True
print(isinstance(my_generator, Iterator)) # 输出True
for num in my_generator:
	print(num)

2)用函数结合yield关键字实现同样功能的生成器

在函数中使用yield关键字,而不是return关键字,代表该函数是生成器。生成器也是一种迭代器,可以使用for循环,每当函数执行到yield时会暂停,等待下次在该位置继续执行。

上面讲到的传入一个数字,返回被2整除的大于0的数用生成器实现如下。

def MyIterator(num):
	current_num = 0
	while current_num <= num:
		print (f'调用生成器 current_num : {current_num}')
		if current_num % 2==0 and current_num!=0:
			temp_num = current_num
			yield temp_num
		current_num += 1
#生成器也是一种迭代器
print(f'生成器 是否是可迭代对象 : {isinstance(MyIterator(10), Iterable)}')
print(f'生成器 是否是迭代器 : {isinstance(MyIterator(10), Iterator)}')
#结果:
生成器 是否是可迭代对象 : True
生成器 是否是迭代器 : True

执行for循环

for i in MyIterator(10):
	print(i)
#结果:
调用生成器 current_num : 0
调用生成器 current_num : 1
调用生成器 current_num : 2
2
调用生成器 current_num : 3
调用生成器 current_num : 4
4
调用生成器 current_num : 5
调用生成器 current_num : 6
6
调用生成器 current_num : 7
调用生成器 current_num : 8
8
调用生成器 current_num : 9
调用生成器 current_num : 10
10

闭坑指南:生成器是一次性的,一旦遍历完,就不能再次使用。如果需要再次使用,需要重新创建生成器对象。

使用itertools模块创建迭代器

import itertools

# 无限迭代器
counter = itertools.count(start=10, step=2)
print(next(counter))  # → 10
print(next(counter))  # → 12

# 排列组合
perms = itertools.permutations('ABC', 2)
print(list(perms))  # → [('A','B'), ('A','C'), ...]

小白:(献上膝盖)原来迭代器这么强大!
专家:(扶起小白)在实际编程中多使用它们,你会对它们有更深入的理解!

相关推荐

Python操作Word文档神器:python-docx库从入门到精通

Python操作Word文档神器:python-docx库从入门到精通动动小手,点击关注...

Python 函数调用从入门到精通:超详细定义解析与实战指南 附案例

一、函数基础:定义与调用的核心逻辑定义:函数是将重复或相关的代码块封装成可复用的单元,通过函数名和参数实现特定功能。它是Python模块化编程的基础,能提高代码复用性和可读性。定义语法:...

等这么长时间Python背记手册终于来了,入门到精通(视频400集)

本文毫无套路!真诚分享!前言:无论是学习任何一门语言,基础知识一定要扎实,基础功非常的重要,找一个有丰富编程经验的老师或者师兄带着你会少走很多弯路,你的进步速度也会快很多,无论我们学习的目的是什么,...

图解Python编程:从入门到精通系列教程(附全套速查表)

引言本系列教程展开讲解Python编程语言,Python是一门开源免费、通用型的脚本编程语言,它上手简单,功能强大,它也是互联网最热门的编程语言之一。Python生态丰富,库(模块)极其丰富,这使...

Python入门教程(非常详细)从零基础入门到精通,看完这一篇就够

本书是Python经典实例解析,采用基于实例的方法编写,每个实例都会解决具体的问题和难题。主要内容有:数字、字符串和元组,语句与语法,函数定义,列表、集、字典,用户输入和输出等内置数据结构,类和对象,...

Python函数全解析:从入门到精通,一文搞定!

1.为什么要用函数?函数的作用:封装代码,提高复用性,减少重复,提高可读性。...

Python中的单例模式:从入门到精通

Python中的单例模式:从入门到精通引言单例模式是一种常用的软件设计模式,它保证了一个类只有一个实例,并提供一个全局访问点。这种模式通常用于那些需要频繁创建和销毁的对象,比如日志对象、线程池、缓存等...

【Python王者归来】手把手教你,Python从入门到精通!

用800个程序实例、5万行代码手把手教你,Python从入门到精通!...

Python从零基础入门到精通:一个月就够了

如果想从零基础到入门,能够全职学习(自学),那么一个月足够了。...

Python 从入门到精通:一个月就够了

要知道,一个月是一段很长的时间。如果每天坚持用6-7小时来做一件事,你会有意想不到的收获。作为初学者,第一个月的月目标应该是这样的:熟悉基本概念(变量,条件,列表,循环,函数)练习超过30个编...

Python零基础到精通,这8个入门技巧让你少走弯路,7天速通编程!

Python学习就像玩积木,从最基础的块开始,一步步搭建出复杂的作品。我记得刚开始学Python时也是一头雾水,走了不少弯路。现在回头看,其实掌握几个核心概念,就能快速入门这门编程语言。来聊聊怎么用最...

神仙级python入门教程(非常详细),从0到精通,从看这篇开始!

python入门虽然简单,很多新手依然卡在基础安装阶段,大部分教程对一些基础内容都是一带而过,好多新手朋友,对一些基础知识常常一知半解,需要在网上查询很久。...

Python类从入门到精通,一篇就够!

一、Python类是什么?大家在生活中应该都见过汽车吧,每一辆真实存在、能在路上跑的汽车,都可以看作是一个“对象”。那这些汽车是怎么生产出来的呢?其实,在生产之前,汽车公司都会先设计一个详细的蓝图...

学习Python从入门到精通:30天足够了,这才是python基础的天花板

当年2w买的全套python教程用不着了,现在送给有缘人,不要钱,一个月教你从入门到精通1、本套视频共487集,本套视频共分4季...

30天Python 入门到精通(3天学会python)

以下是一个为期30天的Python入门到精通学习课程,专为零基础新手设计。课程从基础语法开始,逐步深入到面向对象编程、数据处理,最后实现运行简单的大语言模型(如基于HuggingFace...

取消回复欢迎 发表评论: