迭代器iterator与生成器generator

迭代器

首先来说一下什么是迭代

  • 每一次对过程的重复称为一次“迭代”,而每一次迭代得到的结果会作为下一次迭代的初始值。例如:循环获取容器中的元素。
list01 = [34, 4, 5, 46, 57, 87]
#for item in list01:
  #  print(item)
# 对象可以for的条件是什么?也是for循环的原理
# 对象具有__iter__方法
# 对象可以获取迭代器
# for 原理:
# 1. 调用了__iter__()方法,返回迭代器对象
iterator = list01.__iter__()
while True:
    try:
        # 2. 获取下一个元素
        item = iterator.__next__()
        print(item)
        #item = iterator.__next__()
        #print(item)
    # 3. 如果没有元素,则捕获异常,停止循环。
    except StopIteration:
        break

综上所述,就是迭代的原理
可迭代对象:

  • 定义:具有__iter__函数的对象,可以返回迭代器对象。
    迭代器对象:

  • 定义:可以被next()函数调用并返回下一个值的对象。

  • 语法

      class 迭代器类名:
         def __init__(self, 聚合对象):
              self.聚合对象= 聚合对象 
      
         def __next__(self): 
              if 没有元素:
                  raise StopIteration
              return 聚合对象元素
     -- 聚合对象通常是容器对象
    
  • 迭代器的使用遍及并统一了 Python。在幕后,该for语句调用iter()容器对象。该函数返回一个迭代器对象,该对象定义了__next__()一次访问容器中元素的方法。当没有更多元素时, next()引发一个StopIteration异常,告诉 for循环终止。

举个例子:
如何将迭代器定义到我们的类中:

"""
    迭代器
    迭代自定义对象
"""
class SkillIterator:
    def __init__(self, data):
        self.__data = data
        self.__index = -1

    def __next__(self):
        self.__index += 1
        if self.__index > len(self.__data) - 1:
            raise StopIteration()
        return self.__data[self.__index]


class SkillManager:
    def __init__(self):
        self.__skills = []

    def add_skill(self, skill):
        self.__skills.append(skill)

    def __iter__(self):
        return SkillIterator(self.__skills)


manager = SkillManager()
manager.add_skill("九阳神功")
manager.add_skill("乾大挪移")
manager.add_skill("太极坤")

# for item in manager:
#     print(item)#

# iterator = manager.__iter__()
# while True:
#     try:
#         item = iterator.__next__()
#         print(item)
#     except StopIteration:
#         break

生成器generator

定义:能够动态(循环一次计算一次返回一次)提供数据的可迭代对象。

#生成器函数:含有yield语句的函数,返回值为生成器对象。
def my_range(stop):
    number = 0
    while number < stop:
        yield number
        number += 1
# for item in my_range(5):
#     print(item)  # 0 1 2 3 4

# 惰性操作/延迟操作
my = my_range(5)
iterator = my.__iter__()
while True:
    try:
        item = iterator.__next__()
        print(item)
    except StopIteration:
        break
#要知道的是,yield之前的代码都在__next__()方法中,打个断点调试调试
  • 语法

      -- 创建:
      		def 函数名():
    
      				yield 数据
      
      调用:
       for 变量名 in 函数名():
      	  语句
      调用生成器函数将返回一个生成器对象,不执行函数体,所以呢,要用for循环去拿出数据
      因为for 循环的他会调用__next__()方法(迭代器~)
    

执行过程:

  • (1) 调用生成器函数会自动创建迭代器对象。
    (2) 调用迭代器对象的__next__()方法时才执行生成器函数。
    (3) 每次执行到yield语句时返回数据,暂时离开。
    (4) 待下次调用__next__()方法时继续从离开处继续执行。

生成器 = 可迭代对象(可以参与for循环) + 迭代器(生成数据)

补充:生成器表达式

# 列表推导式
list01 = [34, 43, 54, 65, 67, 7]
list02 = [item for item in list01 if item > 10]
for item in list02:
    print(item)
#生成器表达式,注意跟列表的区别,括号哦~
generator02 = (item for item in list01 if item > 10)
for item in generator02:
    print(item)


for item in (item for item in list01 if item > 10):
    print(item)
上一篇:频繁请求报requests异常的处理


下一篇:vue webpack文件打包后的文件如何本地运行