Python迭代器和生成器

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

一、序列可迭代的原因: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迭代器和生成器)