迭代器
迭代器用于:
- for 循环
- 构建和扩展集合类型
- 逐行遍历文本文件
- 列表推导、 字典推导和集合推导
- 元组拆包
- 调用函数时, 使用 * 拆包实参
解释器需要迭代对象x时,会自动调用iter(x);
内置的iter函数,有以下功能:
- 检查对象是否实现了 _iter _ 方法, 如果实现了就调用它,获取一个迭代器。
- 如果没有实现 _iter _ 方法,但是实现了 _getitem _ 方法,Python 会创建一个迭代器,尝试按顺序(从索引 0 开始)获取元素。
- 如果尝试失败,Python抛出TypeError异常,通常会提示"C objectis not iterable"(C 对象不可迭代),其中C是目标对象所属的类。
__next__ #返回下一个可用的元素,如果没有元素了,抛出StopIteration异常__iter__ #返回self, 以便在应该使用可迭代对象的地方使用迭代器,例如在for循环中
import reRE_WORD = re.compile('\w+')class Sentence: # 可迭代的对象 def __init__(self, text): self.text = text self.words = RE_WORD.findall(text) def __iter__(self): # 1 return SentenceIterator(self.words)class SentenceIterator: # 迭代器 def __init__(self, words): self.words = words self.index = 0 def __next__(self): # 2 try: word = self.words[self.index] except IndexError: raise StopIteration() self.index += 1 return word def __iter__(self): # 3 return selfs = Sentence('"The time has come," the Walrus said,')for word in s: print(word)--------------------ThetimehascometheWalrussaid
- {#}1: 实现__iter__方法,并返回了一个迭代器实例SentenceIterator,所以是可迭代的对象;
- {#}23: 实现__next__和__iter__,并返回了迭代器本身;
- {#}123:说明:迭代器可以迭代,但是可迭代的对象不是迭代器;
生成器
生成器函数
- 只要Python函数的定义体中有yield关键字,那么事实上定义的是一个generator function,调用这个generator function返回值是一个generator。
def gen_AB(): print('start') yield 'A' print('continue') yield 'B' print('end.')print(gen_AB()) # 1gen_AB() # 2for item in gen_AB(): # 3 print('--->', item)----------------start---> Acontinue---> Bend.
- {#}1:虽然函数gen_AB没有return,但是依然返回了生成器对象;
- {#}2:此时没有执行函数gen_AB的内容;
- {#}3:生成器一定是迭代器(反之不成立);
- {#}3: 当调用generator的next方法,generator会执行到yield表达式处,返回yield表达式的内容,然后暂停(挂起)在这个地方,等待下个next的执行;
生成器表达式(generator expression)
- 生成器表达式可以理解为列表推导的惰性版本: 不会迫切地构建列表,
而是返回一个生成器, 按需惰性生成元素。
def gen_AB(): print('start') yield 'A' print('continue') yield 'B' print('end.') res1 = [x*3 for x in gen_AB()] # 1for i in res1: print('-->', i) # 2res2 = (x*3 for x in gen_AB()) # 3for i in res2: print('--->', i)----------------startcontinueend.--> AAA--> BBBstart---> AAAcontinue---> BBBend.
- {#}1:列表推导迫切迭代函数gen_AB,打印出start continue end. res1=[AAA,BBB];
- {#}2: 输出AAA,BBB;
- {#}3:把生成器表达式返回的值赋值给res2。只需调用gen_AB()函数,虽然调用时会返回一个生成器,但是这里并不使用;
参考
- 流畅的Python.