python学习笔记 | 迭代器&生成器

迭代器(iterator)

迭代器是访问集合元素的一种方式。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退。另外,迭代器的一大优点是不要求事先准备好整个迭代过程中所有的元素。迭代器仅仅在迭代到某个元素时才计算该元素,而在这之前或之后,元素可以不存在或者被销毁。这个特点使得它特别适合用于遍历一些巨大的或是无限的集合,比如几个G的文件。

特点:

  1. 访问者不需要关心迭代器内部的结构,仅需通过next()方法不断去取下一个内容
  2. 不能随机访问集合中的某个值 ,只能从头到尾依次访问
  3. 访问到一半时不能往回退
  4. 便于循环比较大的数据集合,节省内存
i = iter('abc') # 定义一个迭代器对象i,该对象定义了一个__next__方法,用于逐一访问容器中的元素
i # <str_iterator at 0x10b5199a0>
i.__next__() # 或next(i)

生成一个迭代器:

class Dragon:
  def __init__(self,count):
    self.count = count
  def __iter__(self):
    return self
  def __next__(self):
    self.count-=1
    if self.count == 1:
      print("别杀了,别杀了,龙妈只有一条龙了!")
      raise StopIteration
    return self.count
D = Dragon(3)

模拟range方法

class Range:
    def __init__(self, start, end, step):
        self.start = start
        self.end = end
        self.step = step
    def __iter__(self):
        return self
    def __next__(self):
        if self.start >= self.end:
            raise StopIteration
        rel = self.start
        self.start += self.step
        return rel

for i in Range(1, 9, 2): print(i,end=',') # 1,3,5,7,

模拟斐波那契数列

class Fib:
  def __init__(self):
    self.a = 0
    self.b = 1
  def __iter__(self):
    return self
  def __next__(self):
    self.a,self.b = self.b,self.a+self.b
    return self.a
  
for i in Fib():
  if i>1000:break
  print(i,end=',') # 1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,

生成器(generator)

在 Python 中,使用了 yield 的函数被称为生成器(generator)。

跟普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。

在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行。

def G(count):
    while count > 1:
        yield count
        count-=1
        
G(5) # <generator object G at 0x10b569ac0>
g = G(5)
g = (i for i in range(1,6))
g.__next__() # 5
g.__next__() # 4

这个yield的主要效果,就是可以使函数中断,并保存中断状态

中断后,下一次调用这个函数,从上次yield的下一句开始执行

def Dragon(count):
  while count > 0:
    yield f'龙妈还剩{count}条龙'
    count -= 1
    
D = Dragon(3)
next(D) # '龙妈还剩3条龙'
next(D) # '龙妈还剩2条龙'
next(D) # '龙妈还剩1条龙'
next(D) # Traceback (most recent call last):
        # File "<input>", line 1, in <module>
        # StopIteration

模拟斐波那契数列:

def Fib(num):
  a = 0
  b = 1
  while b < num:
    yield b
    a,b = b,a+b
    
F = Fib(1000)
for f in F:
  print(f,end=',') # 1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,


919 字