將 Python 物件轉換為迭代器

Shikha Chaudhary 2023年1月30日 2022年5月17日
  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