可迭代对象、迭代器、生成器

序列协议

只要实现了_getitem_ 和 _len_ 就可以看做是序列

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 __getitem__(self, index):
        return self.words[index]
        
    def __len__(self):
        return len(self.words)
        
    def __repr__(self):
        return 'Sentence(%s)' % reprlib.repr(self.text)
序列协议

可迭代原因:iter 函数

迭代对象的流程:

  • 检查对象是否实现了 _iter_,是,则调用它获取一个迭代器
  • 否,检查对象是否实现了 _getitem_,是,则创建一个迭代器从索引 0 开始获取元素
  • 否,抛出 TypeError
collections.abc.Iterable

可迭代对象与迭代器

关系:Python 从 可迭代对象中获取迭代器

s = 'ABC'
it = iter(s)  # 用可迭代对象构建迭代器
while True:
    try:
        print(next(it))
    except StopIteration:  # for循环,列表推导,元祖拆包也会有
        del it
        break

生成器函数

定义:定义体中含有 yield 关键字的函数。调用生成器函数返回生成器对象。生成器产出值。


生成器函数

生成器函数执行过程

生成器表达式

惰性,当 for 循环迭代时,才会执行函数定义体


生成器表达式

标准库生成器函数

  • filter(predicate, it)
    接受一个断言参数 predicate 和一个迭代器参数。当 predicate(item) 为 True 时,保留。
  • enumerate(it, start=0)
    产出 (index, item),其中 index 从start 开始计数。
  • map(func, it)
    产出 func(item)
  • zip(it1, ..., itN)
    产出由 N 个元素组成的元祖,只有有一个可迭代对象迭代尽了就停止。
  • itertools.zip_longest(it1, ..., itN, fillvalue=None)
  • itertools.chain(it1, ..., itN)
合并多个迭代对象的生成器函数
  • reversed(seq)
    倒序产出 seq 元素

yield from

不同生成器结合在一起使用。
代替嵌套迭代,直接与最内层生成器联系起来。


yield from

可迭代的归约函数

  • all(it)
  • any(it)
  • max(it, [key=, default=])
  • min(it, [key=, default=])
  • reduce(func, it[, initial])
  • sum(it, start=0)
    虽然每个归约函数都可以用 functools.reduce 来代替,但有一项优化措施 reduce 做不到:一旦确定结果立即停止迭代
短路

all([])

I already read the docs, and I know the implementation

 def all(iterable):
    for element in iterable:
        if not element:
            return False
    return True

But the question is why not?

def all(iterable):
    if not iterable:
        return False
    for element in iterable:
        if not element:
            return False
    return True

深入分析 iter 函数

iter
  • iter 的第一个参数是可调用对象,不断产生值,第二个参数是哨符,当产出这个值时,抛出 StopIteration,停止迭代。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 容器(container) 容器是一种把多个元素组织在一起的数据结构,容器中的元素可以逐个地迭代获取,可以用in,...
    不_一阅读 287评论 0 0
  • 傻傻分不清 可迭代对象 举例:容器如字符串、列表、元组、字典、集合,文件对象和管道对象,迭代器 可通过for..i...
    某米狼阅读 346评论 0 1
  • 三十年河东,三十年河西。 有谁会想到整日里被自己欺负的人,有朝一日可以飞黄腾达,盛极一时呢? 有谁会想到胆小懦弱窝...
    厉羽悠君阅读 223评论 1 1
  • 毕业聚会的那天,大家都喝多了,就连平时严厉的班主任也拉着大家伙扯东扯西的。可那一天方白没有来。恐怕只有我和林逸注意...
    世言阅读 210评论 0 0
  • 王者荣耀100条上分小技巧 1.阵容越完整的队伍,团战时更有优势,上单、打野、中单、射手、坦克/辅助,5个位置越完...
    中坤创投阅读 989评论 0 2