簡體   English   中英

對python中的“迭代器”感到困惑

[英]Confused about “iterators” in python

我正在使用Beginning Python:從新手到專業的書學習python,我對討論iterators的部分感到困惑。 本節有一個例子:

>>> Class Fibs:
...    def __init__(self):
...        self.a = 0
...        self.b = 1
...    def __next__(self):
...        self.a, self.b = self.b, self.a + self.b
...        return self.a
...    def __iter__(self):
...        return self
...
>>> fibs = Fibs()
>>> for f in fibs:
...     if f > 1000:
...         print(f)
...         break
...
1597

說實話,我只知道fibs是一個方法__next____iter__的對象,但不知道循環的每一步發生了什么。 我做了一個測試:

>>> isinstance(f, Fibs)
False
>>> f is fibs
False
>>> isinstance(f, int)
True
>>> fibs.a
1597

這讓我更加困惑! 為什么f is fibs的布爾值f is fibsFalse 為什么在執行循環后fibs.a變為1597?(方法__next__是否在循環中自動調用?)提前感謝。

 1  fibs = Fibs()
 2  for f in fibs:
 3      if f > 1000:
 4          print(f)
 5          break

第1行創建一個Fibs()對象,調用__init__() 第2行調用__iter__() ,它返回一個迭代器對象(在本例中,只是fibs本身)。 然后解釋器將重復調用__next__()方法; 它返回一個普通數字self.a ,它被分配給循環變量f (當然它不是Fibs()對象,當然也不是名為fibs的那個)。 當該值達到1000時,將觸發if子句,打印結果並跳出循環。

為什么在執行循環后fibs.a變為1597?

那么這是因為它正在經歷Fibonacci序列 ,這是序列中第一個超過1000的數字。

0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584 ...

在輸入循環解釋器時調用__iter__方法。 在每個循環步驟中,解釋器調用Fibs __next__方法。

是的,循環自動調用__next__

for循環對給定對象執行此操作:

# turn the object into an iterator
iterator = iter(given_object)
while True:
    try:
        # try to get the next value
        next_value = next(iterator)
    except StopIteration
        # for loop is done, run the `else:` block if there is any
        run_for_else_suite()
        break
    else:
        # set the loop target to `next_value`
        assign_next_value(next_value)
        continue = run_loop_body()
        if not continue:
            break

iter()函數調用given_object.__iter__() ,而next()函數調用given_object.__next__() ; 這些函數提供了一些額外的功能,是調用迭代器API的正確方法。

因此,在每次循環迭代中, f被賦予Fib.__next__方法返回的值。

你還可以看到Fib是它自己的迭代器; __iter__返回self 其他類型可以返回專用的迭代器對象; 列表做,例如:

>>> iter([])
<listiterator object at 0x129516610>

返回專用迭代器允許您在對象上創建多個“視圖”,其中每個迭代器都保持自己的位置,如嵌套循環:

lst = [1, 2, 3]
for i in lst:
    for j in lst;
        print (i, j)  # prints (0, 0), (0, 1), (0, 2), (0, 3), (1, 0), etc.

或者您可以顯式重用迭代器:

lst = [1, 2, 3]
lst_iter = iter(lst)
for i in lst_iter:
    for j in lst_iter:
        print (i, j)  # prints (0, 1), (0, 2)
for f in fibs

隱式調用fibs.__iter__fibs.__iter__f綁定到它產生的所有對象。 這些對象都不是Fibs實例,更不用說等於fibs 整體(大致)相當於

# boilerplate, implicit in the "for" notation
__iterator = iter(fibs)
while True:
    try:
        f = next(__iterator)
    except StopIteration:
        break

    # your code, with f now bound to what the iterator yielded
    if f > 1000:
        print(f)
        break

iternext分別是調用__iter____next__的簡潔方法。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM