将 Python 对象转换为迭代器

Shikha Chaudhary 2023年1月30日
  1. 在 Python 中使用 __iter__()__next__() 方法将对象转换为迭代器
  2. Python 中迭代器的属性
  3. 结论
将 Python 对象转换为迭代器

Python 中的迭代器是我们将循环遍历的那些项,或者换句话说,迭代。我们可以将任何对象更改为迭代器,甚至可以在 __iter__()__next__() 方法的帮助下创建我们的迭代器。

当我们必须以迭代器的形式访问某些对象时,它很有用。我们可以使用生成器循环来做到这一点,但是这些很耗时并且会使代码变得庞大。

Python 的内置方法 __iter__() 更适合此类任务。

在 Python 中使用 __iter__()__next__() 方法将对象转换为迭代器

顾名思义,迭代器会一一返回数据值。迭代器对象在 __iter__()__next__() 方法的帮助下执行此操作。

__iter__()__next__() 方法一起构成了迭代器协议。让我们讨论一些例子来理解迭代器协议的基本工作。

demo = ("volvo", "ferrari", "audi")
val = iter(demo)

print(next(val))
print(next(val))
print(next(val))

输出:

volvo
ferrari
audi

在这里,我们有一个包含三个值的元组。我们使用 __iter__() 方法从这个元组对象中一一获取值。

此外,__next__() 方法一个接一个地遍历这些值。我们可以不同地使用 __next__() 方法,就像这样。

demo = ("volvo", "ferrari", "audi")
val = iter(demo)

print(val.__next__())
print(val.__next__())
print(val.__next__())

输出:

volvo
ferrari
audi

现在我们也得到了相同的输出。PEP 3114iterator.next() 更改为 iterator.__next__()。我们可以将这些方法与任何可迭代对象一起使用。

这是一个使用字符串的示例。

demostr = "volvo"
val = iter(demostr)

print(next(val))
print(next(val))
print(next(val))
print(next(val))
print(next(val))

输出:

v
o
l
v
o

Python 有许多可迭代的内置容器——字符串、列表、元组。我们可以使用 __iter__() 函数从可迭代对象中创建对象。

此外,我们可以使用 __next__() 方法逐个访问对象。

语法:

iter(object_name)
iter(callable, sentinel)

在这里,object_name 指的是对象,如列表或元组,其迭代器将被创建。此外,callable 是指可调用对象,sentinel 是指给出迭代终止条件的值。

sentinel 值显示了我们正在迭代的序列的结尾。因此,如果我们在所有对象都已经被迭代时调用迭代器,我们会得到 StopIterationError 异常。

请注意,创建迭代器不会更改可迭代对象。看看这个演示 StopIterationError 的示例。

li = ["volvo", "ferrari", "audi"]

value = li.__iter__()
print(value.__next__())
print(value.__next__())
print(value.__next__())
print(value.__next__())  # Error occurs here

输出:

volvo
ferrari
audi

StopIteration

我们甚至可以创建我们的对象或类作为迭代器。让我们创建一个迭代器,它将返回一个数字序列,从 10 开始,其中每个值将增加 2。

class GetNumbers:
    def __iter__(self):
        self.x = 10
        return self

    def __next__(self):
        a = self.x
        self.x += 2
        return a


myclass = GetNumbers()
value = iter(myclass)

print(next(value))
print(next(value))
print(next(value))
print(next(value))
print(next(value))

输出:

10
12
14
16
18

在这里,__iter__() 方法的工作方式类似于 __init__() 方法。我们可以在 __iter__() 方法中进行初始化或操作,但我们总是返回对象。

我们可以在 __next__() 方法的帮助下执行操作。但在这种情况下,返回值应该是序列的下一个元素。

在这里,我们将 2 添加到 __next__() 方法中的每个值。

Python 中迭代器的属性

为了理解内部工作,我们应该知道迭代器的一些属性。这些如下:

  1. 迭代对象使用内部计数变量来保持迭代计数。
  2. 一旦迭代完成,我们不能再次将此迭代计数变量重新分配为 0。因此,出现 StopIteration 错误。
  3. 因此,我们可以说迭代计数变量只能遍历一个容器一次。

这里是文档链接,谈到了 Python 中的迭代器。

现在让我们看看迭代永远不会结束的情况。这里值得注意的一点是我们使用了 __next__() 方法一定次数。

但是如果迭代器对象永远不会耗尽呢?在这种情况下,不可能多次编写 __next__() 语句。

我们使用带有两个参数的 iter() 方法。第一个参数是可调用的,第二个参数是哨兵。

因此,当返回值与哨兵匹配时,迭代器停止。将以下代码粘贴到你的编辑器中并尝试运行它。

int()
value = iter(int, 1)
next(value)

输出:

>>> 1
1
>>> 1
1
>>> 2
2
>>> 3
3
>>>

当你运行这段代码时,你会看到迭代器永远不会停止。这是因为 int() 函数每次都返回 0

不管你给什么值作为输入,返回的值都不会与 sentinel 相同,这里是 1。尝试将 sentinel 的值更改为 0。

int()
value = iter(int, 0)
next(value)

输出:

StopIteration

这一次,我们在第一次运行时得到了 StopIteration 异常。

我们创建迭代器的方式,我们也可以创建无限迭代器。让我们创建一个无限迭代器,它将返回所有偶数的列表。

class Even:
    def __iter__(self):
        self.x = 0
        return self

    def __next__(self):
        x = self.x
        self.x += 2
        return x

输出:

>>> obj = iter(Even())
>>> next(obj)
0
>>> next(obj)
2
>>> next(obj)
4
>>>

使用迭代器的最大优点是它们可以帮助我们节省资源。请注意,如果我们使用变量,将会浪费大量空间。

但是在迭代器的帮助下,我们可以得到所有偶数,而不用担心将它们存储在内存中。

要了解有关 Python 中迭代器对象的更多信息,请参阅此文档

结论

在本文中,我们讨论了 Python 中迭代器的概念。我们讨论了 __iter__()__next__() 方法的工作原理以及一些示例。

当我们想要使用无限值时,我们还看到了迭代器的使用如何提高内存效率。我们还使用迭代器协议制作了迭代器。

相关文章 - Python Iterator