美文网首页
Iterable, Iterator

Iterable, Iterator

作者: SkyDavid | 来源:发表于2016-03-25 14:07 被阅读0次

    在 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 模块提供了许多迭代器和迭代器有关的函数.

    相关文章

      网友评论

          本文标题:Iterable, Iterator

          本文链接:https://www.haomeiwen.com/subject/tfdakttx.html