迭代器---生成器

迭代器---生成器

一、迭代器

三、生成器

回到顶部

一、迭代器

1.迭代

  含义:  通过迭代器不断取出可迭代对象中的下一个元素的过程

  可迭代对象: 能被迭代的对象

  方法:  

    判断迭代器是否是可迭代对象 : isinstance(对象, Iterable) 

    判断迭代器对象是否是迭代器 : isinstance(对象, Iterator)

2.迭代器 

  含义: 迭代的访问 可迭代对象中的下一个元素

  导入模块 : from collections import Iterator

  应用场景 : 用户只需要关心如何使用迭代器访问数据 而不需要关键数据该如何访问 

#!/usr/bin/env python
# _*_ coding:utf-8 _*_
# Author:Mr.yang
from collections import Iterator
from collections import Iterable

# 1.迭代器 - 记录每次访问的位置信息的对象 便于下一次访问(当访问完成后会自动执行下一个位置)
# 2.应用场景 不同可迭代对象有不同的访问方式 每一种可迭代对象都会提供一个迭代器
#            用户只需要用迭代器取出 下一个元素 即可,而不应具体范文细节  - 解耦合

# 3.自定义迭代器类型 实现__next__方法
class MyRangeIter(object):
    """迭代器类"""
    def __init__(self, n):
        self.n = n
        self.i = 0

    def __next__(self):
        """实现迭代器类型 一定要实现该方法 目的:返回用户需要的下一个元素的值"""
        if self.i < self.n:
            self.i += 1
            return self.i
        else:
            # 停止 迭代 当迭代器完成的时候 抛出这个异常'
            raise  StopIteration

    def __iter__(self):
        """python规定迭代器也必学是可迭代对象  因此使用此方法"""
        return self

class MyRange(object):
    """可迭代类型"""
    def __init__(self, n):
        self.n = n

    def __iter__(self):
        """实现一个可迭代类型 一定要实现本方法 目的"返回一个迭代器"""
        return MyRangeIter(self.n)

# 4.判断迭代器类型
# print("判断迭代器类型",isinstance(MyRangeIter(5), Iterator))
# print("判断迭代器是否是可迭代对象",isinstance(MyRangeIter(5), Iterable))
# print("判断迭代器对象是否是迭代器",isinstance(MyRange(5), Iterator))


for i in MyRange(5):
    print(i)
    input(":")
示例代码  

二、生成器

1.生成器表达式

  列表推导式 [ ] ---> ()

    优点 : 节约资源,不占用大量空间, 在用户需要访问数据的时候 , 才延迟产生

a = (x +1 for x in range(5))
print(a.__next__())
print(a.__next__())


#### 打印结果 ####
1
2
示例

2.生成器函数

  定义 : 

     有yield关键字的函数 不再是普通函数 而是生成器函数

     简单来说:只要在def中有yield关键字的 就称为 生成器

  yelid关键字:

1.执行到yield会暂停当前代码执行 将后面的值返回到调用生成器代码的地方

2 .当前生成器代码再次执行时 直接从上次暂停的地方继续往下执行

           send关键字:

        如果第一次启动生成器使用send方法,那么参数只能传入None,一般第一次启动生成器使用next函数

#!/usr/bin/env python
# _*_ coding:utf-8 _*_
# Author:Mr.yang
def myrange(n):
    start = 0
    while start < n :
        number = yield  start
        print("接收道路数据%s" % number)
        start += 1

if __name__ == '__main__':
    gen = myrange(3)
    # 生产器支持操作-next函数 迭代器支持的操作
    i = next(gen)
    print(i)
    # 生成器支持操作-send方法 特有
    i = gen.send(None)
    print(i)
    # 对比 两种执行生成器的方式的异同
    # 1 同 : 都可以执行生成器代码 并且获取到一个值
    # 2 异:  next不可以发送数据; send可以发送数据;
    #        第一次调用时send(None),next没有这个要求
示例

    return 和 yelid 区别:      

 yield: 每次启动生成器都会返回一个值,多次启动可以返回多个值,也就是yield可以返回多个值

 return: 只能返回一次值,代码执行到return语句就停止迭代

#!/usr/bin/env python
# _*_ coding:utf-8 _*_
# Author:Mr.yang

def myrange(n):
    start = 0
    while start < n:
        yield start
        # return "呵呵"
        print("------")
        start += 1

# 生成器函数不是普通函数 调用函数()产生print(next(gen))生成器对象
# 执行生成器函数的代码 需要调用next(生成器对象)
gen = myrange(5)
i = next(gen)
print(i)
try:
    print(next(gen))
except Exception as e:
    # 如果需要获取到 生成器最终return的值 需要捕获异常
    print("接收的异常数据: %s" % e)

# print(next(gen))
# print(next(gen))
# print(next(gen))
# print(next(gen))
示例

        

猜你喜欢

转载自www.cnblogs.com/Mryang123/p/10003479.html