Python 自定义迭代器

在本文中,我们将了解什么是迭代器以及如何借助 __iter____next__ 类方法创建自定义迭代器。 我们还将学习如何在 Python 生成器的帮助下创建自定义迭代器。


借助 Python 中的类方法 __iter____next__ 创建自定义迭代器

现在,当您说迭代器时,顾名思义,它将用于迭代。

如果您来自 C、C++ 和 Java 等语言,我们有一个共同的概念:++。 当我们谈论迭代时,还知道了一个概念:for 循环。

假设我们有一个包含 5 个元素的列表。 使用循环,我们可以从第一个元素迭代到最后一个元素。

这样,我们就有了一个包含一些值的列表,如果我们想使用索引号一一打印它们。

如果我们传递索引 0,它将为我们提供第一个元素 2。如果我们使用索引值 1,它将为我们提供第二个元素 5。

Numbers=[2,5,10,3,1]

print(Numbers[0])
print(Numbers[1])

输出:

2
5

打印值的另一种方法是使用循环。 我们可以迭代列表并打印所有值。

Numbers=[2,5,10,3,1]

for i in Numbers:
    print(i)

输出:

2
5
10
3
1

现在我们还有另一种方法:使用迭代器。 一般来说,迭代器在 for 循环的幕后工作。

我们将使用 iter() 函数来理解迭代器,它将我们的列表转换为迭代器。 这个迭代器不会给我们所有的值; 它一次只会给出一个值。

Numbers=[2,5,10,3,1]

ITR=iter(Numbers)
print(ITR)

我们可以看到它正在打印迭代器的对象。

<list_iterator object at 0x000001FEDCFF7310>

但是,如果您想要该值,可以设置 ITR.__next__(),这是一个内置方法。 它将在第一次调用特定对象的 __next__() 方法时为我们提供第一个值; 这与我们使用索引值的方式相同,但优点是我们不必使用索引值。

umbers=[2,5,10,3,1]

ITR=iter(Numbers)
print(ITR.__next__())

输出:

2

当我们在下一个执行行执行 ITR.__next__() 时,它将给出下一个值。 在这一场景的背后,迭代器将有多个值,因此当我们调用 __next__() 方法时,它将获取一个值。

同样,当我们调用 __next__() 时,它知道 i 的最后一个值,这意味着它将保留最后一个值的状态。 这就是迭代器的美妙之处; 当我们再次调用该函数时,它将保留旧值。

我们可以使用类创建迭代器。 使用该类,我们可以单独打印前 10 个值。

为了实现这一点,我们将有一个名为 TopValues 的类,在这个类中,我们将指定一个计数器。

为此,我们将使用 __init__ 函数,在其中定义计数器变量 self.N=1; 显然,计数器将从 1 开始初始化。我们需要两个重要的方法来创建自定义迭代器。

第一个是 iter() 方法,它将为我们提供迭代器的对象,然后 next() 方法将提供下一个值或对象。 在 __next__ 方法中,我们不返回 self.N,而是使用一个名为 VALUE 的变量,在其中分配 self.N,并在下一行中将 self.N 加一。

这样它将在每次下一次迭代中递增,然后返回 VALUE 而不是 self.N,因为 self.N 在下一次迭代中递增。

class TopValues:
    def __init__(self):
        self.N=1

    def __iter__(self):
        return self
    def __next__(self):
        VALUE=self.N
        self.N+=1
        return VALUE

我们的迭代器现在已准备就绪,以便我们可以创建 TopValues 类的对象。 让我们使用循环,因为通常当你有迭代器时,我们可以使用循环。

T_Val=TopValues()

for i in T_Val:
    print(i)

现在,当我们执行这段代码时,我们会得到数千个值。

1
2
3
4
5
....
1000

让我们尝试了解发生了什么。 要检查迭代器是否正常工作,我们将使用 __next__()

print(T_Val.__next__())

该行将打印第一个迭代值 1,但是循环出了什么问题? 问题是循环将从头到尾进行; 我们假设终点是 10,但我们没有提到应该在哪里停止。

当我们使用循环时,它会调用 next() 函数,这就是它的工作原理。 for循环内部使用 next() 函数; 因此,它会一次又一次地调用这个 next() 函数。

我们必须在 __next__ 方法中应用一个条件。

我们还必须设置 else 块; 在这个块中,我们将引发一个异常。 否则,在打印 10 个值后,循环将打印 None 值。

class TopValues:
    def __init__(self):
        self.N=1

    def __iter__(self):
        return self
    def __next__(self):
        if self.N<=10:
            VALUE=self.N
            self.N+=1
            return VALUE
        else:
            raise StopIteration


T_Val=TopValues()

for i in T_Val:
    print(i)

输出:

1
2
3
4
5
6
7
8
9
10

在 Python 生成器的帮助下创建自定义迭代器

现在让我们尝试创建一个执行相同操作的生成器函数。 生成器要简单得多,因为它们为我们处理 __iter__()__next__() 方法。

如果我们尝试编写一个名为 Our_Gen() 的生成器函数,我们将在该函数内传递参数。

由于我们循环遍历列表,因此我们一次生成一项。 而且,当没有更多的项目可以循环时,它将自动处理该问题并引发停止迭代的异常。

现在我们正在循环 Our_Gen() 函数,因此它应该一次打印一项。 如果我们运行它,我们可以看到我们一次得到一个。

def Our_Gen(n_list):
    for i in n_list:
        yield i

Func=Our_Gen([2,5,10,3,1])

for i in Func:
    print(i)

输出:

2
5
10
3
1

确保我们的 next() 函数仍然有效。 执行后,我们得到五个元素,我们得到一个停止迭代异常。

def Our_Gen(n_list):
    for i in n_list:
        yield i

Func=Our_Gen([2,5,10,3,1])

print(Func.__next__())
print(Func.__next__())
print(Func.__next__())
print(Func.__next__())
print(Func.__next__())
print(Func.__next__())

输出:

2
5
10
3
1
Traceback (most recent call last):
  File "c:\Users\Dell\Desktop\demo\demo.py", line 56, in <module>
    print(Func.__next__())
StopIteration

生成器比类更容易编写。 但根据您的用例,您可能需要知道如何在类中执行 __iter__() 方法和 __next__() 方法。

你可能感兴趣的:(Python,实用技巧,python,开发语言)