Python中的迭代器你了解吗

 更新时间:2023年05月24日 09:54:13   作者:答案永恒  
迭代器是一种特殊的对象,它实现了迭代协议,允许按照一定的顺序逐个访问元素,本文就来带大家深入了解一下Python中迭代器的使用,需要的可以参考下

for loop和迭代器

在Python中,for循环是一种常用的迭代结构,用于遍历可迭代对象中的元素。迭代器是一种特殊的对象,它实现了迭代协议,允许按照一定的顺序逐个访问元素。

for循环和迭代器之间存在密切的关系,实际上,for循环是基于迭代器工作的。当使用for循环遍历可迭代对象时,Python会在内部自动创建一个迭代器对象,并使用该迭代器来逐个获取元素,直到所有元素都被访问完毕。

for loop里面in后面那个东西必须是一个iterable, 也就是必须是一个可迭代对象

下面是一个示例,演示了for循环和迭代器之间的关系:

fruits = ['apple', 'banana', 'orange']

# 使用for循环遍历列表元素
for fruit in fruits:
    print(fruit)

# 上述代码等价于下面的迭代器方式
iterator = iter(fruits)  # 创建迭代器对象
while True:
    try:
        fruit = next(iterator)  # 获取下一个元素
        print(fruit)
    except StopIteration:
        break

在上面的示例中,我们首先使用for循环遍历了列表fruits中的元素,打印出每个水果的名称。然后,我们手动创建了一个迭代器对象iterator,并使用next()函数逐个获取元素,直到遇到StopIteration异常,表示所有元素都被访问完毕。

可以看到,使用for循环可以简化迭代过程,不需要显式地创建迭代器对象和处理StopIteration异常。Python的许多内置对象(如列表、元组、字典等)都是可迭代的,因此可以直接在for循环中使用它们。

列表

lst = [1, 2, 3]
for i in lst:
    print(i)

字典

d = {"a": 1, "b": 2}
for i in d:
    print(i)

文件操作

with open(my.txt, "r") as f:
    for i in f:
        print(i)

除了内置的可迭代对象,你还可以自定义迭代器类,实现自己的迭代逻辑。这样,你就可以在for循环中使用自定义的迭代器来遍历特定的数据结构或实现特定的迭代行为。

for loop的背后核心是迭代器可迭代对象

迭代器和可迭代对象

https://docs.python.org/3/glossary.html

在Python中,可迭代对象和迭代器是两个相关但不同的概念。

可迭代对象(Iterable)是指实现了__iter__()方法的对象,或者实现了__getitem__()方法且可按照顺序访问的对象。这两者都是为了保证它可以在iter这个函数的作用下返回一个iterator。可迭代对象可以被迭代,也就是可以在for循环中使用。常见的可迭代对象包括列表、元组、字符串、字典、集合等。

迭代器(Iterator)是一种特殊的对象,它实现了迭代协议,具有__iter__()__next__()方法。迭代器用于逐个返回可迭代对象中的元素,每次调用__next__()方法都会返回下一个元素,如果没有更多元素,则引发StopIteration异常。迭代器对象还可以在迭代过程中记录迭代状态。

每当使用for循环来遍历一个可迭代对象时,Python会在内部自动创建一个迭代器对象,并调用其__next__()方法来逐个获取元素。因此,可以说for循环是基于迭代器工作的。

下面是一个示例,演示了可迭代对象和迭代器的概念:

fruits = ['apple', 'banana', 'orange']

# fruits是可迭代对象,可以在for循环中使用
for fruit in fruits:
    print(fruit)

# 创建迭代器对象
iterator = iter(fruits)

# 调用迭代器的__next__()方法获取下一个元素
print(next(iterator))  # 输出:'apple'
print(next(iterator))  # 输出:'banana'
print(next(iterator))  # 输出:'orange'
print(next(iterator))  # 引发StopIteration异常

在上面的示例中,fruits是一个可迭代对象,我们可以直接在for循环中使用它来遍历元素。同时,我们也可以使用iter()函数手动将可迭代对象转换为迭代器对象,并使用next()函数来逐个获取元素。当所有元素都被访问完毕时,继续调用next()函数会引发StopIteration异常。

需要注意的是,迭代器是一种一次性的对象,即在迭代过程中,一旦迭代器返回了所有元素,它就会耗尽,无法再次使用。如果想重新遍历可迭代对象,需要重新创建迭代器对象。

  • 一个iterable更像是一个数据的保存者,一个container,它是可以没有状态的,它可以完全不知道你这个iterator数到哪了,它需要有能力产生一个iterator。
  • iterator一定是有状态的,但是它并不需要实现一个container,它当然内部肯定知道它代表这个iterable里面是什么数据。iterator必须要有__next__这个method。这个method保证它在被next作用的时候可以返回下一个iterable。

自定义一个可迭代对象和对应的迭代器-链表

#! -*-conding=: UTF-8 -*-
# 2023/5/22 18:43

class NodeIter:
    def __init__(self, node):
        self.curr_node = node

    def __next__(self):
        if self.curr_node is None:
            raise StopIteration
        node, self.curr_node = self.curr_node, self.curr_node.next

        return node


class Node:
    def __init__(self, name):
        self.name = name
        self.next = None

    def __iter__(self):
        return NodeIter(self)


node1 = Node("node1")
node2 = Node("node2")
node3 = Node("node3")

node1.next = node2
node2.next = node3


if __name__ == '__main__':
    for node in node1:
        print(node.name)

如果我们想在for loop里面使用链表的话,那我们就要自己把链表变成一个iterable。

这段代码演示了如何自定义一个可迭代对象和对应的迭代器。

首先,我们定义了一个Node类,表示一个节点,每个节点具有一个名称和一个指向下一个节点的引用。Node类实现了__iter__()方法,该方法返回一个迭代器对象。

然后,我们定义了一个NodeIter类作为迭代器,它接收一个节点对象作为参数,并在__init__()方法中初始化当前节点。NodeIter类实现了__next__()方法,用于返回下一个节点。在每次调用__next__()方法时,它会将当前节点作为结果返回,并将当前节点更新为下一个节点。当没有更多节点时,抛出StopIteration异常。

最后,在if __name__ == '__main__':条件下,我们使用自定义的可迭代对象和迭代器进行遍历。通过for node in node1:的语法,会自动调用node1对象的__iter__()方法获取迭代器,并通过迭代器逐个获取节点,并打印节点的名称。

运行以上代码,输出结果为:

node1
node2
node3

这个示例展示了如何自定义可迭代对象和迭代器,并在for循环中使用它们实现自定义的迭代逻辑。

到此这篇关于Python中的迭代器你了解吗的文章就介绍到这了,更多相关Python迭代器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • python GUI编程(Tkinter) 创建子窗口及在窗口上用图片绘图实例

    python GUI编程(Tkinter) 创建子窗口及在窗口上用图片绘图实例

    这篇文章主要介绍了python GUI编程(Tkinter) 创建子窗口及在窗口上用图片绘图实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-03-03
  • Python+seaborn实现联合分布图的绘制

    Python+seaborn实现联合分布图的绘制

    联合分布(Joint Distribution)图是一种查看两个或两个以上变量之间两两相互关系的可视化图,在数据分析操作中经常需要用到。本文将通过seaborn实现绘制联合分布图,需要的可以参考一下
    2023-02-02
  • Python获取时间戳的多种方法总结

    Python获取时间戳的多种方法总结

    时间戳是一个表示日期和时间的数值,通常以秒为单位,在Python中,获取时间戳是常见的任务,用于记录事件、计时操作、以及在各种应用中跟踪时间,本文将介绍多种获取时间戳的方法,包括标准库和第三方库的方式,并提供示例代码以帮助你更好地理解
    2023-11-11
  • Python中最强大的重试库Tenacity使用探索

    Python中最强大的重试库Tenacity使用探索

    这篇文章主要为大家介绍了Python中最强大的重试库Tenacity使用探索,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-12-12
  • 基于梯度爆炸的解决方法:clip gradient

    基于梯度爆炸的解决方法:clip gradient

    今天小编就为大家分享一篇基于梯度爆炸的解决方法:clip gradient,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-02-02
  • Python爬虫爬取电影票房数据及图表展示操作示例

    Python爬虫爬取电影票房数据及图表展示操作示例

    这篇文章主要介绍了Python爬虫爬取电影票房数据及图表展示操作,结合实例形式分析了Python爬虫爬取、解析电影票房数据并进行图表展示操作相关实现技巧,需要的朋友可以参考下
    2020-03-03
  • 使用Python实现图片批量重命名工具

    使用Python实现图片批量重命名工具

    这篇文章主要为大家介绍了一个基于Python开发的图形界面工具,用于批量重命名文件夹中的图片文件,文中的示例代码讲解详细,感兴趣的小伙伴可以参考下
    2025-04-04
  • Python自定义装饰器原理与用法实例分析

    Python自定义装饰器原理与用法实例分析

    这篇文章主要介绍了Python自定义装饰器原理与用法,结合实例形式较为详细的分析了Python自定义装饰器,带参数的装饰器等概念、原理、实现方法及相关使用技巧,需要的朋友可以参考下
    2018-07-07
  • Python实现清理重复文件功能的示例代码

    Python实现清理重复文件功能的示例代码

    在电脑上或多或少的存在一些重复文件,体积小的倒没什么,如果体积大的就很占内存了。本文用python制作了一个删除重复文件的小工具,核心代码很简单,希望对你有所帮助
    2022-07-07
  • 如何将numpy二维数组中的np.nan值替换为指定的值

    如何将numpy二维数组中的np.nan值替换为指定的值

    这篇文章主要介绍了将numpy二维数组中的np.nan值替换为指定的值操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-05-05

最新评论