zoukankan      html  css  js  c++  java
  • Python-迭代器与生成器

    一、迭代器

    迭代:是一个重复的过程,但每次重复都是基于上一次的结果而来的
    迭代器:就是一种不依赖于索引的取值工具

    为什么要用迭代器:

    1.迭代器是一种通用的迭代取值方法(可以无视是否有索引)
    2.惰性计算,节省内存。迭代器在生成时,并没有产生值,并不会占用很多内存。在每次使用next方法后,会临时计算一个值,更节省内存。

    迭代器的优点:

    ①、是一种通用的迭代取值方案
    ②、惰性计算,节省内存

    如何用迭代器:

    在下面我们会使用到双下划线加方法名的使用,其实和iter(),next()是等同的

    dic = {"name": "yang", 'age': 18, 'gender': "male"}
    dic_iterator = dic.__iter__()
    
    res1 = dic_iterator.__next__()
    res2 = dic_iterator.__next__()
    res3 = dic_iterator.__next__()
    print(res1,res2,res3)
    ------------------------------------
    name age gender
    
    
    dic_iterator.__next__()  # 第四次next()抛出异常
    -----------------------------------
    StopIteration
    '''
    当迭代器中取完了值之后,会抛出异常,提示我们已经取完了值,抛出StopIteration,
    因为在我们直接拿到一个迭代器的时候,我们是不知道这个迭代器到底有多少个值的
    '''
    while True:
        try:
            res = dic_iterator.__next__()
            print(res)
        except StopIteration:
            break
    '''
    try:
        代码
    except 异常类型:
        代码
    是一种处理异常的情况,和java的异常处理机制try,catch类似,目前我们只需要记住这个格式,他而已帮助我们捕获异常,在出现了我们指定的异常的时候,会帮助我们执行下部的代码,防止程序崩溃
    '''
    

    二:可迭代对象与迭代器对象

    可迭代对象/类型

    内置有__iter__方法的类型称之为:可迭代的对象/类型
    所有的常用类型,都是可以被转成迭代器的对象,也叫可迭代对象
    1、字典dict
    2、集合set
    3、文件对象(也是迭代器对象)

    f = open('a.txt')
    f.__iter__()
    

    4、字符串str
    5、列表list
    6、元组tuple

    迭代器对象

    迭代器对象: 内置有__next__方法、内置有__iter__方法

    可迭代对象可以用iter()方法转化成迭代器对象,迭代器对象也可以再使用iter方法,但是得到的是它本身,这个特性是为了迎合for循环的工作原理,下面会讲到。
    对于文件对象,它既是可迭代对象,又是迭代器对象,做成这样的原因是因为某些文件可以很大,因为迭代器的特性,每次调用才产生值,不会造成内存冲击,而其他的类型,一般不会存放非常大量的数据。

    三:for循环的工作原理

    dic = {"name": "egon", 'age': 18, 'gender': "male"}
    
    dic_iterator = dic.__iter__()
    while True:
        try:
            res = dic_iterator.__next__()
            print(res)
        except StopIteration:
            break
    
    for k in dic:
        print(k)
    '''
    步骤1 dic_iterator = dic.__iter__()
    步骤2 k=dic_iterator.__next__(),执行循环体代码
    步骤3 循环往复,直到抛出异常,for循环会帮我们捕捉异常结束循环
    '''
    dic = {"name": "egon", 'age': 18, 'gender': "male"}
    dic_iterator = dic.__iter__()
    for k in dic_iterator:
        print(k)
    
    print(dic_iterator)
    

    四、生成器

    生成器 = 自定义迭代器
    但凡是函数内出现了yield关键字,调用函数不会执行函数整体代码,而是得到一个返回值,这个返回值就是生成器。

    def func():
        print("hello1")
        yield 111
        print("hello2")
        yield 222
        print("hello3")
        yield 333
    
    g = func()
    print(g)  # 生成器本质就是迭代器
    res=next(g)
    print(res)
    
    res=next(g)
    print(res)
    
    res=next(g)
    print(res)
    
    # next(g)  此行会报错,因为取值完毕了
    -----------------------
    hello1
    111
    hello2
    222
    hello3
    333
    

    yield与return:

    (1)相同点:都可以用来返回值
    (2)不同点:
    return只能返回一次值,函数就立即结束了
    yield能返回多次值,yield可以挂起函数(即停住函数)

    # 案例
    def func():
         res=0
         while True:
             res+=1
             yield res
    
    g=func()
    
    for i in g:
        print(i)
    -----------
    死循环
    

    迭代器的优缺点:

    优点:
    1、是一种通用的迭代取值方案
    2、惰性计算,节省内存
    缺点:
    1、取值不如索引、key的取值方式灵活
    2、取值是一次性的,只能往后取,不能预估值的个数
    小练习:用迭代器写一个简单的range功能

    def my_range(start, stop, step=1):
       while start < stop:
           yield start
           start += step
    
    for i in my_range(1,5,2):
        print(i)
    

  • 相关阅读:
    P2015 二叉苹果树(树形DP)
    Treats for the Cows (区间DP)
    You Are the One(区间DP 好题)
    Palindrome subsequence (区间DP)
    Cutting Sticks(区间DP)
    L2-013 红色警报 (dfs判断图连通性)
    L2-001 紧急救援 (dijkstra+dfs回溯路径)
    多线程 -- JMM、volatile关键字、内存屏障、happens-before原则、缓存一致性
    多线程 -- 各种锁的概念
    Spring Boot 学习笔记(十六)启动原理、运行流程、自动配置原理
  • 原文地址:https://www.cnblogs.com/chiyun/p/14066310.html
Copyright © 2011-2022 走看看