Python iter() 函数

Python iter() 语法

iter() 是 Python 的一个内置函数,它用于获取一个可迭代对象对应的迭代器。

语法:

iter(iterable, sentinel)

说明:

iter() 函数接收以下 2 个参数。

  • iterable(必选):它是一个可迭代对象。Python 常见的内置可迭代对象有:列表、元组、字符串、字典等。
  • sentinel(可选):用于设置结束值(即哨兵值)。如果 iter() 设置了第 2 个参数,那么当使用循环遍历迭代器时,如果当前循环值与 sentinel 值相同时,循环就会结束。

如果一个对象是可迭代对象,那么它就肯定实现了 __iter__() 方法,该方法会返回一个迭代器。迭代器的内部实现了 __next__() 方法,该方法返回迭代的下一个值。当迭代器没有值可以迭代时,__next__() 方法会抛出 StopIteration 异常。

注意:

  • iter() 返回的迭代器是惰性求值的,它不会一次性生成所有元素并存储在内存中。
  • 一旦迭代器被遍历完,它就耗尽了,无法再次使用,需要重新调用 iter() 来获取一个新的迭代器。

Python iter() 摘要

使用频率
官方文档 查看
相关函数 next()aiter()anext()

Python iter() 示例

接下来,我们通过几个简单的例子来讲解一下 Python iter() 函数是如何使用的。

示例 1:iter() 的参数是可迭代对象

# 列表
nums = [1, 2, 3, 4, 5]
print(iter(nums))

# 元组
colors = ('red', 'green', 'blue')
print(iter(colors))

# 字符串
s = 'Python'
print(iter(s))

# 字典
users = {'Jack': 1001, 'Lucy': 1002, 'Tony': 1003}
print(iter(users))

# range 对象
items = range(5)
print(iter(items))

运行结果如下。

<list_iterator object at 0x000001D16722C9A0>
<tuple_iterator object at 0x000001D16722C9B0>
<str_iterator object at 0x000001D16722C9C0>
<dict_keyiterator object at 0x000001D167222D40>
<range_iterator object at 0x000001D1670A3CB0>

分析:

从上面可以知道,不同可迭代对象对应的迭代器是不一样的。常见的可迭代对象对应的迭代器如下表所示。

可迭代对象对应的迭代器
可迭代对象 对应的迭代器
list list_iterator
tuple tuple_iterator
str str_iterator
dict dict_keyiterator
range range_iterator

示例 2:iter() 的参数是非可迭代对象

year = 2024
print(iter(2024))

运行结果如下。

(报错) TypeError: 'int' object is not iterable

分析:

并非所有对象都是可迭代的,只有可迭代对象才能使用 iter() 函数(或 __iter__() 方法)。如果对一个不可迭代的对象使用 iter() 函数,则 Python 会直接报错(抛出 TypeError 异常)。

到这里小伙伴肯定会问:“使用 iter() 函数来获取一个可迭代对象的迭代器,到底有什么用呢?” 其实只有获取了迭代器,才可以使用 next() 函数来不断获取下一次的迭代结果。

示例 3:next() 获取迭代结果

colors = ['红', '绿', '蓝']
result = iter(colors)

print(next(result))
print(next(result))
print(next(result))

运行结果如下。

红
绿
蓝

示例 4:iter() 带第 2 个参数

class Double:
    def __init__(self):
        self.start = 1
    def __iter__(self):
        return self
    def __next__(self):
        self.start *= 2
        return self.start
    __call__ = __next__

result = iter(Double(), 32)
for x in result:
    print(x)

运行结果如下。

2
4
8
16

分析:

在上面例子中,我们使用 iter() 函数的第 2 个参数(即 sentinel 参数)来停止迭代。当迭代到 32 时,就会停止迭代。

iter() 函数和 __iter__() 方法

如果想要获取一个可迭代对象对应的迭代器,除了 iter() 函数之外,我们还可以使用 __iter__() 方法。两者功能是等价的,只是语法不一样而已。

示例 5:iter() 和 __iter__()

colors = ['红', '绿', '蓝']

print(iter(colors))
print(colors.__iter__())

运行结果如下。

<list_iterator object at 0x000002904CAB9BA0>
<list_iterator object at 0x000002904CAB9BA0>

常见问题

1. 为什么有时候我们需要手动获取迭代器?

在 Python 中,当我们使用 for 循环遍历一个可迭代对象(比如列表、字符串等)时,Python 背后会自动调用 iter() 来获取迭代器,然后不断调用 next() 来获取下一个元素,直到出现 StopIteration 异常。

那么,为什么我们还需要手动调用 iter() 来获取迭代器,或者手动调用 next() 呢?主要有以下几个原因:

  • 精细控制迭代流程:有时候我们可能不希望一次性遍历完所有元素。手动获取迭代器并使用 next() 可以让我们在特定条件下停止、暂停或按需获取下一个元素,实现更复杂的逻辑。
  • 处理无限序列:如果有一个会无限生成数据的可迭代对象(比如一个从传感器不断读取数据的对象),我们不能用 for 循环去遍历它,因为它永远不会停止。这时,我们可以手动获取迭代器,然后只在需要的时候调用 next()。
  • 理解迭代机制:显式地使用 iter() 和 next() 有助于我们深入理解 Python 迭代协议的底层工作原理,这对于编写高效且符合 Python 习惯的代码非常有帮助。
  • 构建复杂的数据处理管道:在函数式编程或构建数据流时,我们可能需要将迭代器作为参数传递给其他函数,或者在不同的阶段对同一个迭代器进行操作,手动获取迭代器会让你有更大的灵活性。

2. 如何自定义迭代器?

如果希望自定义类对象能够像 Python 内置的列表或字符串一样,支持 for 循环遍历,或者能够被 iter() 函数处理,我们就需要使得该类成为一个可迭代对象,并且能够返回一个迭代器。

想要实现这一点,我们需要在类中自行实现 __iter__() 和 __next__() 这两个 “魔法方法”:

  • __iter__():这个方法必须返回一个迭代器对象。通常,如果类本身就实现了 __next__() 方法,那么 __iter__() 可以简单地返回 self。如果迭代逻辑比较复杂,你也可以返回一个单独的迭代器类实例,或者一个生成器(使用 yield 关键字)。
  • __next__():这个方法负责返回序列中的下一个元素。当没有更多元素可以返回时,它必须抛出 StopIteration 异常,以此来通知迭代结束。

上一篇: any()

下一篇: next()

给站长反馈

绿叶网正在不断完善中,小伙伴们如果发现任何问题,还望多多给站长反馈,谢谢!

邮箱:lvyenet@vip.qq.com

「绿叶网」服务号
绿叶网服务号放大
关注服务号,微信也能看教程。
绿叶网服务号