美文网首页
Python迭代器和生成器

Python迭代器和生成器

作者: Rnben | 来源:发表于2018-12-26 23:07 被阅读0次

    所有的生成器都是迭代器;
    从可迭代的对象中获取迭代器

    一、序列可迭代的原因:iter函数

    迭代对象x时,自动调用iter(x)

    1. 检查是否实现__iter__方法,返回一个迭代器。
    2. 没有实现则,__getitem__方法(参数从0开始),创建一个迭代器,尝试按顺序获取元素。
    3. 如果失败,抛出TypeError异常,"C object is not iterable"

    从Python3.4开始,检查对象能否迭代最准确的方法是调用iter(x)函数,不过没有必要吧。

    二、可迭代的对象与迭代器

    标准的迭代器接口有两个方法:

    1. 无参__next__方法, 返回下一个可用元素,否则抛出StopIteration异常
    2. __iter__返回self,以便于在使用可迭代对象的地方使用迭代器,例如for循环

    经典迭代器

    import re
    import reprlib
    
    RE_WORD = re.compile('\w+')
    
    class Sentence:
        def __init__(self, text):
            self.text = text
            self.words = RE_WORD.findall(text)
    
        def __repr__(self):
            return 'Sentence(%s)' % reprlib.repr(self.text)
            
        def __iter__(self):
            return SentenceIterator(self.words)
    
    class SentenceIterator:
        def __init__(self, words):
            self.words = words
            self.index = 0
    
        def __next__(self):
            try:
                word = self.words[self.index]
            except IndexError:
                raise StopIteration()
            self.index += 1
            return word
    
        def __iter__(self):
            return self  
    

    可迭代对象一定不能是自身的迭代器(可迭代对象必须实现iter方法,但不能实现迭代器)

    三、生成器函数简化经典迭代器

    import re
    import reprlib
    
    RE_WORD = re.compile('\w+')
    
    class Sentence:
        def __init__(self, text):
            self.text = text
            self.words = RE_WORD.findall(text)
    
        def __repr__(self):
            return 'Sentence(%s)' % reprlib.repr(self.text)
            
        def __iter__(self):
            for word in self.words:
                yield word
            # return
    

    函数返回值。生成器函数返回生成器。生成器产出或生成值。

    四、惰性实现

    import re
    import reprlib
    
    RE_WORD = re.compile('\w+')
    
    class Sentence:
        def __init__(self, text):
            self.text = text
    
        def __repr__(self):
            return 'Sentence(%s)' % reprlib.repr(self.text)
            
        def __iter__(self):
            for match in RE_WORD.finditer(self.text):
                yield match.group()
            # return
    

    五、生成器表达式

    import re
    import reprlib
    
    RE_WORD = re.compile('\w+')
    
    class Sentence:
        def __init__(self, text):
            self.text = text
    
        def __repr__(self):
            return 'Sentence(%s)' % reprlib.repr(self.text)
            
        def __iter__(self):
            return(match.group() for match in RE_WORD.finditer(self.text))
    

    六、关于生成器的更多内容

    生成器也可以用来生成不受数据源限制的值。
    标准库中的生成器函数
    Python 3.3 新增 yield from 代替循环,还有...

    相关文章

      网友评论

          本文标题:Python迭代器和生成器

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