• 迭代器与生成器


     迭代器, 生成器

    • 练习: 说出如下代码的打印结果

       
        >>> def foo():
        ...    print(111)
        ...    yield 222
        ...    print(333)
        ...    yield 444
        ...    print(555)
        >>> n = foo()
        >>> next(n)
        >>> next(n)
        >>> next(n)
       
    • generator: 生成器是一种特殊的迭代器, 不需要自定义 __iter____next__

      • 生成器函数 (yield)

      • 生成器表达式

    class Range:
        def __init__(self, start, end=None, step=1):
            if end is None:
                self.end = start
                self.start = 0
            else:
                self.start = start
                self.end = end
            self.step = step
        def __iter__(self):
            return self
        def __next__(self):
            if self.start < self.end:
                current = self.start
                self.start += self.step
                return current
            else:
                raise StopIteration()
     
    • iterator: 任何实现了 __iter____next__ 方法的对象都是迭代器.

      • __iter__ 得到一个迭代器。迭代器的__iter__()返回自身

      • __next__ 返回迭代器下一个值

      • 如果容器中没有更多元素, 则抛出 StopIteration 异常

      • Python2中没有 __next__(), 而是 next()

    • str / bytes / list / tuple / dict / set 自身不是迭代器,他们自身不具备 __next__(), 但是具有 __iter__(), __iter__() 方法用来把自身转换成一个迭代器

    • 练习1: 定义一个随机数迭代器, 随机范围为 [1, 50], 最大迭代次数 30

        import random
        class RandomIter:
            def __init__(self, start, end, times):
                self.start = start
                self.end = end
                self.count = times
            def __iter__(self):
                return self
            def __next__(self):
                self.count -= 1
                if self.count >= 0:
                    return random.randint(self.start, self.end)
                else:
                    raise StopIteration()
       
    • 练习2: 自定义一个迭代器, 实现斐波那契数列

       
        class Fib:
            def __init__(self, max_value):
                self.prev = 0
                self.curr = 1
                self.max_value = max_value
            def __iter__(self):
                return self
            def __next__(self):
                if self.curr <= self.max_value:
                    res = self.curr
                    self.prev, self.curr = self.curr, self.prev + self.curr  # 为下一次做准备
                    return res
                else:
                    raise StopIteration()
       
    • 练习3: 自定义一个生成器函数, 实现斐波那契数列

        def fib(max_value):
            prev = 0
            curr = 1
            while curr < max_value:
                yield curr
                prev, curr = curr, curr + prev
       
    • 迭代器、生成器有什么好处?

      • 节省内存

      • 惰性求值 (惰性求值思想来自于 Lisp 语言)

    • 各种推导式

      • 分三部分:生成值的表达式, 循环主体, 过滤条件表达式

      • 列表: [i * 3 for i in range(5) if i % 2 == 0]

      • 字典: {i: i + 3 for i in range(5)}

      • 集合: {i for i in range(5)}

  • 相关阅读:
    [luoguP2463] [SDOI2008]Sandy的卡片(后缀数组 + st表)
    [luoguP3302] [SDOI2013]森林(主席树 + 启发式合并 + lca)
    [luoguP2526] [SHOI2001]小狗散步(二分图最大匹配)
    [luoguP3231] [HNOI2013]消毒(最小点覆盖 + 状压)
    [luoguP1963] [NOI2009]变换序列(二分图最大匹配)
    [luoguP1129] [ZJOI2007]矩阵游戏(二分图最大匹配)
    [luoguP1640] [SCOI2010]连续攻击游戏(二分图最大匹配)
    [luoguP2569] [SCOI2010]股票交易(DP + 单调队列)
    SICP:2,4 序对的过程性表示方法
    SICP:1.43重复调用函数
  • 原文地址:https://www.cnblogs.com/gugubeng/p/9755226.html
Copyright © 2020-2023  润新知