zoukankan      html  css  js  c++  java
  • 迭代器

    1. 迭代器简介

    1.1 什么是迭代器

    看过装饰器之后,大家都知道了器就是工具,装饰器是用来装饰的工具,迭代器就是用来迭代的工具

    那什么是迭代呢? 迭代一般都是用来取值的 , 所以

    # 迭代器指的是迭代取值的工具,迭代是一个重复的过程,
    # 每次重复都是基于上一次的结果而继续的,两次重复是有关系的,单纯的重复并不是迭代
    

    1.2 为什么要有迭代器

    既然迭代器是迭代取值,而涉及到把多个值取出来的数据类型有 :

    • 列表 字符串 元组 字典 集合 文件句柄 range( )对象
    l = ['ymn', 'tom', 'jack']
    i = 0
    while i < len(l):
        print(l[i])
        i += 1
    

    上述取值的方式确实是迭代取值,但是有一定的局限性,都是通过索引迭代取值的,但是我们知道有些数据类型是

    没有索引的,没有办法通过索引取值,所以python必须提供一种能够不依赖索引的取值方式,所以有了迭代器

    1.3 如何使用迭代器

    如何使用迭代器的前提就是怎样才能创建一个迭代器?我们知道要用变量直接赋值一个,比如name = "ymn"

    迭代器是通过可迭代对象转变而来的,意思就是说你要先有个可迭代器对象,然后通过某种方法可以把可迭代器

    对象转化成迭代器,这个时候你肯定又迷了,tmd迭代器什么?可迭代对象又是什么?可迭代对象实际上我们

    经常使用只是你不知道他还可以叫做可迭代对象而已

    2. 可迭代对象

    前提 : 在python中万物皆是对象,变量是对象,函数是对象等等等

    在python中我们把具有__iter__方法的对象都称之为可迭代对象,我们来看一下那些对象具有__iter__方法

    l = []
    l.__iter__()
    
    s = "ymn"
    s.__iter__()
    
    t = (1,)
    t.__iter__()
    
    d = {}
    d.__iter__()
    
    set1 = set()
    set1.__iter__()
    
    with opne('a.txt',mode="r",encoding="utf-8") as f:
        f.__iter__()    # 彩蛋
    
    r = range(1,10)
    r.__iter__()
    

    我靠,tmd你发现以前学的好多都是可迭代对象。

    3. 可迭代对象转化成迭代器

    通过一个可迭代器对象转换为迭代器简直不要太简单,直接调用可迭代对象的__iter__方法就能返回一个迭代器

    l = ['ymn', 'tom', 'jack']
    l_iterator = l.__iter__()
    print(l_iterator)         # <list_iterator object at 0x000002B271ADD518>
    

    迭代器对象内置具有__next____iter__方法,通过方法可以从迭代器中取值

    l = ['ymn', 'tom', 'jack']
    l_iterator = l.__iter__()
    
    print(l_iterator.__next__())    # ymn
    print(l_iterator.__next__())    # tom	
    print(l_iterator.__next__())    # jack
    print(l_iterator.__next__())    # 报错,因为迭代器里面的值已经取完了
    

    强调 :迭代器中的值只能取一次,一旦取出来后就不在里面了,不是像列表,元组。

    既然迭代器取值,只用__next__方法就行了,为什么还要有__iter__方法呢?我们来看一下__iter__方法返

    回什么

    l = ['ymn', 'tom', 'jack']
    l_iterator = l.__iter__()
    
    
    print(l_iterator)                # <list_iterator object at 0x000001B36963D518>
    print(l_iterator.__iter__())     # <list_iterator object at 0x000001B36963D518>
    

    发现迭代器调用__iter__方法之后还是迭代器,那tmd要它何用,不如剁了,不急看完for循环的工作原理你就

    知道了

    4. for循环的工作原理

    for循环取值实际上就是把可迭代对象转换为迭代器,然后调用__next__方法,那为什么for循环就知道什么时候

    取的是最后一个值呢?就能保证不报错呢?实际上for也不知道什么时候取的是最后一个值,只不过for循环内部做

    了异常处理。

    l = ['ymn', 'tom', 'jack']
    l_iterator = l.__iter__()
    
    while 1:
        try:                             # 尝试执行
            ret = l_iterator.__next__()
            print(ret)
        except StopIteration:            # 捕获到异常退出循环
            break
            
            
    for x in l    # 这句代码实际上内部做的就是上面那些操作
    

    但是 : 如果in后面的对象本身就是一个迭代器呢?,如果他没有__iter__方法,你就不能for循环了,既然是取

    值,就应该让for循环也可以直接操作迭代器,于是python在迭代器中又内置了一个__iter__方法,调用之后返回

    返回自己实际上我们用的文件句柄就是迭代器,他具有__iter____next__两个方法

    with opne('a.txt',mode="r",encoding="utf-8") as f:
        f.__iter__() 
        f.__next__()
    

    5. 迭代器的优缺点

    优点

    • 迭代器提供一种不依赖于索引的取值方式,这样可以遍历没有索引的可迭代对象

    • 迭代器与列表比较,迭代器是进行惰性计算的,更省内存

    缺点

    • 无法获取迭代器长度,不如使用索引取值灵活
    • 迭代器只能遍历一次,不能回退
    • 必须依靠可迭代对象转换,可迭代器对象耗内存
  • 相关阅读:
    一、【注解】Spring注解@ComponentScan
    一致性Hash算法
    垃圾回收器搭配和调优
    JVM的逃逸分析
    简单理解垃圾回收
    类加载机制和双亲委派模型
    VMWare15下安装CentOS7
    HBase协处理器(1)
    依赖注入的三种方式
    Javascript-设计模式_装饰者模式
  • 原文地址:https://www.cnblogs.com/xcymn/p/14081660.html
Copyright © 2011-2022 走看看