Iterable, Iterator

在 Python 中,迭代特性遠比我們想象中運用的多,很多我們平常忽略的東西都用到對象能迭代的特性,比如

  • for
  • collection type construction and extension
  • looping over text file line by line
  • list, dict, set comprehension
  • unpacking
  • many built-in function

Iterable 與 Iterator
Iterable 返回一個 Iterator (通過定義 __iter__ 方法)
Iterator 要求定義 __iter____next__ 其中前者往往返回 self,后者逐個返回元素直到沒有元素時拋出 StopIteration

檢測一個對象是不是 Iterator 最好的方法是 isinstance(obj, abc.Iterator), 即是你的 obj 不是繼承自 abc.Iterator,但只要你的對象實現了 __iter____next__ 方法就會返回 True

還有要注意的一點是最好把 Iterable 和 Iterator 分開,原因是 Iterable 往往要求能多次迭代,而 Iterator 迭代完后就沒有了

一個最為普通的 Iterator

import re

RE_WORD = re.compile('\w+')

class Sentence:
    def __init__(self, text):
        self.words = RE_WORD.findall(text)

    def __iter__(self):
        return SentenceIterator(self.words)

class SentenceIterator:
    def __init__(self, words):
        self.words = words
        self.index = index

    def __next__():
        try:
            word = self.words[self.index]
        except IndexError:
            raise StopIteration
        self.index += 1
        return word

    def __iter__():
        return self

顯然這樣定義很繁瑣,所以 Python 中有很多語法糖來幫助你 :)

Generator Function
Generator Function 是含有 yield 的函數,調用 Generator Gunction 返回一個 Generator 對象,而 Generator 對象內部實現了 Iterator 協議,因此支持迭代

class Sentence:
    def __init__(self, text):
        self.words = RE_WORD.findall(text)

    def __iter__(self):
        for word in self.words:
            yield word

還可以讓我們上面 Sentence 的實現更加 Lazy,節約內存

class Sentence:
    def __init__(self, text):
        self.text = text

    def __iter__(self):
        for match in RE_WORD.finditer(self.text):
            yield match.group()

Python 中類似 list comprehension, 還有 generator comprehension, 作為 generator function 的語法糖,generator comprehension 直接返回一個 generator 對象

class Sentence:
    def __init__(self, text):
        self.text = text

    def __iter__(self):
        return (match.group() for match in RE_WORD.finditer(self.text))

推薦閱讀: Generator Tricks for Systems Programmers

TODO:

itertoolsfunctools 模塊提供了許多迭代器和迭代器有關的函數.

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容