迭代器和生成器--附加zip

迭代器使用

在迭代器使用之前,先举个例子:

list01 = [1,2133,345,5,6]
# for item in list01:
#     print(item)

# for 循环原理:
#  1. 获取迭代器对象
#  2. 循环获取下一个元素
#  3. 遇到StopIteration停止迭代


# 可以被for的条件(什么是可迭代对象):
# 可以获取迭代器对象(具有__iter__方法)


#1. 获取迭代器对象
iterator =  list01.__iter__()
#2. 获取下一个元素
item = iterator.__next__()
print(item)
print(iterator.__next__())
print(iterator.__next__())
print(iterator.__next__())
print(iterator.__next__())
#3. 直到错误 StopIteration 停止
print(iterator.__next__()) 
iterator =  list01.__iter__()


while True:
    try:
        print(iterator.__next__())
    except StopIteration:
        break # 跳出循环

练习题1:(“悟空”,“八戒”,“唐僧”,“沙僧”,“女儿国国王”)
使用while + 迭代器 获取元组所有元素

tuple = ('悟空','八戒','唐僧','沙僧','女儿国国王')
tuple1 = tuple.__iter__()
while True:
    try:
        print(tuple1.__next__())
    except StopIteration:
        break
 结果:
		悟空
		八戒
		唐僧
		沙僧
		女儿国国王

练习2:{“悟空”:2000,“八戒”:3000,“唐僧”:1000,“沙僧”:2800}
不使用for,获取字典所有元素

dict1 = {'悟空':2000, '八戒':3000, '唐僧':1000, '沙僧':2800, }
dict01 = dict1.__iter__()
while True:
    try:
        key = dict01.__next__()
        value = dict1[key]
        print(key,value)
    except StopIteration:
        break
 结果:
		唐僧 1000
		沙僧 2800
		八戒 3000
		悟空 2000

以上的两个代码都是将元组、字典里的元素逐个打印出来。这种我们认为是迭代的使用。

可迭代对象iterable:

每一次对过程的重复称为‘迭代一次’,每一次重复的结果作为下一次迭代的初始值。
可迭代对象iterable:

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

  2. 语法:

    ---创建的过程
        class 可迭代对象类名:
            def__iter__(self)
        ---使用
        for 变量名 in 可迭代对象:
            语句
    
  3. 原理:

    变量 = 可迭代对象.__iter__()
        while True:
            try:
                元素 = 变量.__next__()
            except:
                break
    

迭代器iterator:

按照惯例,还是还有个参考代码:
4. 参考代码:
```
“”"
迭代器
“”"

class Skill:
    pass


class SkillIterator:
    """
        技能迭代器
    """

    def __init__(self, target):
        self.target = target
        self.index = 0

    # def __next__(self):
    #     item = self.target[self.index]
    #     self.index += 1
    #     return item

    def __next__(self):
        # 如果索引越界  则停止迭代
        if self.index >= len(self.target):
            raise StopIteration()

        item = self.target[self.index]
        self.index += 1
        return item


class SkillManager:
    def __init__(self, skills):
        self.skills = skills

    def __iter__(self):
        # 1. 创建迭代器对象
        # 2. 传递需要迭代的数据
        return SkillIterator(self.skills)


manager = SkillManager([Skill(), Skill(), Skill()])
# for item in manager:
#     print(item)

iterator = manager.__iter__()
# 使用迭代器获取manager中的技能列表
while True:
    try:
        item = iterator.__next__()
        print(item)
    except:
        break

```
  1. 定义:具有__next__的对象,可以获取下一个元素。

  2. 语法:

    class 迭代器名称:
            def __init__(self,参数):
                self.数据 = 参数    #数据就是聚合对象
            def __next__():
                if 没有元素:
                    raise Stoplteration  #停止迭代
                return 数据中的元素#聚合对象的元素
    
  3. 作用:使用者只需要通过一种方式__next__,便可简单明了的获取聚合对象中的元素

  4. 练习题:

    参照下列代码。自定义MyRange类。实现以下效果
    参照代码:
    for item in range(5)
        print(item) #0 1 2 3 4
    实现代码:
    for item in MyRange(5):
        print(item) #0 1 2 3 4     
    
    习题答案:
    class MyRangeIterator:
    #迭代器
        def __init__(self, stop):
            self.stop = stop
            self.start = 0
    
        def __next__(self):
        #创建可迭代对象
            if self.start >= self.stop:
                raise StopIteration()
            temp = self.start
            self.start += 1
            return temp
    
    
    class MyRange:
        def __init__(self, stop):
            self.stop = stop
    
        def __iter__(self):
            return MyRangeIterator(self.stop)
    
    
    for item in MyRange(5):
        print(item)  # 0  1   2   3 4
    

迭代———yield:

还是以上述代码为例:

class Skill:
    pass


# class SkillIterator:
#
#     def __init__(self, target):
#         self.target = target
#         self.index = 0
#
#     def __next__(self):
#         # 如果索引越界  则停止迭代
#         if self.index >= len(self.target):
#             raise StopIteration()
#         item = self.target[self.index]
#         self.index += 1
#         return item


class SkillManager:
    def __init__(self, skills):
        self.skills = skills

    def __iter__(self):# 15:30 上课
        # SkillIterator(self.skills)
        # 本质:
        #     解释器检测到yield关键字,就会生成迭代器对象。
        # 自动生成迭代器的大致规则:
        #     1. yield 关键字以前的代码会放到__next__方法中
        #     2. yield 关键字后面的数据会作为__next__方法的返回值
        # 现象:
        #     调用当前方法时,不执行。
        #     当调用__next__方法时,才执行。
        #     执行到 yield 关键字,暂时离开。
        #     当再次调用__next__方法时,继续执行。
        #     执行到 yield 关键字,暂时离开。
        #     .....

        # print("我的第一次")
        # yield self.skills[0]
        #
        # print("我的第二次")
        # yield self.skills[1]
        #
        # print("我的第三次")
        # yield self.skills[2]

        for i in range(len(self.skills)):
            yield  self.skills[i]


manager = SkillManager([Skill(), Skill(), Skill()])
# for item in manager:
#     print(item)

iterator = manager.__iter__()
while True:
    try:
        item = iterator.__next__()
        print(item)
    except Exception as e:
        print(type(e))
        break

生成器generator:

  1. 生成器的本质:

    """生成器本质
    class MyRangeIterator:
        def __init__(self, stop):
            self.stop = stop
            self.start = 0
    
        def __next__(self):
            if self.start >= self.stop:
                raise StopIteration()
            temp = self.start
            self.start += 1
            return temp
    
    
    class MyGenerator:
        def __init__(self, stop):
            self.stop = stop
    
        def __iter__(self):
             return MyRangeIterator(self.stop)
    
    for item in MyGenerator(5):
        print(item)
        
    g01 = MyGenerator(5)
    iter01 = g01.__iter__()
    while True:
        try:
            print(iter01.__next__())
        except:
            break
    """
    
  2. 练习题:将MyRange修改为yield

    def my_range(stop):
        start = 0
        while start < stop:
            yield start
            start += 1
    
    for item in my_range(5):
        print(item)  # 0  1   2   3 4
    
  3. 定义:能够动态(循环一次,计算一次返回一次)提供数据的可迭代对象

  4. 作用:在循环过程中,按照某种算法推算数据,不必创建容器存储完整的结果,而节省内存空间,数据量越大,优势越明显

  5. 惰性操作:在需要的时候才计算结果,

生成器函数:

  1. 定义:含有yield关键字的函数,返回值是生成器对象,

  2. 语法:

    --创建:
            def 方法名():
                ...
                yield 数据
        --使用
        for 变量名 in 方法名():
            语句
    
  3. 本质:

    --创建
        class 生成器名称:
            def __iter__(self):
                return 迭代器对象
        --使用
        生成器变量名 = 生成器名称()
        迭代器变量名 = 变量名.__iter__()
        while True:
            try:
                print(迭代器变量名.__next__())
            except:
                break
    
  4. 语法说明:

    --调用生成器函数会返回迭代器对象,不执行函数体。
        --执行过程:
            1.调用生成器函数,自动创建迭代器对象,
            2.调用迭代器对象的__next__()方法才执行生成器函数体
            3.每次执行到yield关键字是返回数据,暂时离开。
            4.带下次调用__next__()方法继续执行。
    
  5. 生成迭代器对象原理:

     1.将yield关键字以前的代码放到__next__()方法中。
     2.将yield关键字以后的数据作为__next___()方法返回值。
    

生成器表达式

按照惯例,先熟悉代码。
list01 = [2,3,4,5]

# list02 = []
# for item in list01:
#     list02.append(item ** 2)

# 列表推导式
list02 = [item ** 2 for item in list01] # 执行过后,内存中就存储了所有数据
for item in list02:
    print(item)
# 生成器表达式
g03 = (item ** 2 for item in list01) # 执行过后,没有计算结果。
print(g03)
for item in g03: # 循环一次  计算一次  返回一次
    print(item)
  1. 语法:(表达式 for 变量 in 可迭代对象 [if 条件])
  2. 定义:用推导式语法创建的生成器对象。

zip-----将多个可迭代对象的元素组合成一个个元组:

  1. zip:将多个可迭代对象的元素组合成一个个元组

  2. 练习:

    """
        # 练习:my_zip
        list02 = ["A", "B", "C"]
        for item in zip(list01, list02):
            print(item)
    """
    
    def my_zip(target01,target02):# *args
        for i in range(len(target01)):
            yield (target01[i],target02[i])
    
    list01 = ["a", "b", "c"]
    list02 = ["A", "B", "C"]
    
    for item in my_zip(list01, list02):
        print(item)
    
  3. 练习2:

    list01 = ["a", "b", "c"]
    
    
    # enumerate : 将列表中的每个元素 与 索引 组合为一个元组 16:28
    # for item in enumerate(list01):
    #     print(item[0],item[1])
    
    def my_enumerate(list_target):
        index = 0
        for item in list_target:
            yield (index, item)
            index += 1
    for item in my_enumerate(list01):
    	print(item[0], item[1])
    
    for index, item in my_enumerate(list01):
    	print(index, item)
    
    
    
    #练习:my_zip
    #zip:将多个可迭代对象的元素组合成一个个元组。
    
    list02 = ["A", "B", "C"]
    for item in zip(list01, list02):
    	print(item)
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值