• 迭代器


    一、定义

      1.iterator.(迭代器)

      2.iterable.(可迭代的)

        一般来说,可以被for循环的就是可以迭代的,迭代器一定可以迭代,但是可迭代的类型不一定是迭代器。

    二、说明

      1.有__iter__方法,说明可迭代

    def shili1():
        print(dir([]))     
    #告诉我列表拥有的所有方法
        print(dir(()))
        print(dir(''))
        print(dir(range(10)))
    
        ret=set(dir([]))&set(dir(''))&set(dir({}))&set(dir(range(10)))
        print(ret)    
    #有一个'__iter__'

       判断一下这些类型有没__iter__方法

    print('__init__' in dir(int))
    print('__init__' in dir(list))
    print('__init__' in dir(dict))
    print('__init__' in dir(set))
    print('__init__' in dir(tuple))
    print('__init__' in dir(enumerate))
    print('__init__' in dir(range(10)))
    print('__iter__' in dir(int))           #false
    print('__iter__' in dir(bool))      #false
    print('__iter__' in dir(list))
    print('__iter__' in dir(dict))
    print('__iter__' in dir(set))
    print('__iter__' in dir(tuple))
    print('__iter__' in dir(enumerate))
    print('__iter__' in dir(range(10)))

      2.#setstate指定从那个位置开始取(一般是从0位开始)

       一个可迭代的类型执行了iter之方法后的返回值就是一个迭代器

    print(set(dir([].__iter__())) - set(dir([])))
    # {'__setstate__', '__next__', '__length_hint__'}

      3.示例1(可迭代的不一定是迭代器,迭代器一定可迭代)

    print('*'*40)
    l=[1,2,3]
    iterator=l.__iter__()
    print(iterator.__next__())   #l内部没有next方法,调用iter之后的返回值有next
    print(iterator.__next__())   #l内部没有next方法,调用iter之后的返回值有next
    print(iterator.__next__())   #l内部没有next方法,调用iter之后的返回值有next
    # print(iterator.__next__())   #报错
    # 不能被循环的: not iterable(不可迭代的)   ->    __iter__   ->只要含有iter就可迭代且都可以被for循环   ->   可迭代协议

      4.创建一个iterator

    #[].__iter__()拿到一个
    #可迭代协议
    #在for循环时先找__iter__方法,如果没有就
    #迭代器协议->内部含有next方法和__init__方法的就是迭代器
    print('__iter__' in dir([].__iter__()))
    
    from collections import Iterable
    from collections import Iterator
    
    print(isinstance([],Iterator))  #isinstace判断是否是。迭代器,迭代类型。列表不是迭代器,但是可迭代。
    print(isinstance([],Iterable))
    
    class A:
        # def __init__(self):pass
        def __next__(self):pass      #同时有next和init就是迭代器。next可以一个一个获取值
        # def __iter__(self):pass    #有iter就可用被迭代
    
    a=A()
    print(isinstance(a,Iterable))
    print(isinstance(a,Iterator))
    
    #只要是迭代器一定可迭代,可迭代的不一定是迭代器
    #可迭代的.__init__()方法可以得到一个迭代器

    三、作用
      使用迭代器的好处是可以节省内存空间

    #用迭代器的好处:从容器类型中一个一个的取值,会把所有值都取到
    # 可以节省内存空间(迭代器并不会再占用一大块内存,而是随着循环,每次生成一个,每次next给一个
    #range,文件句柄
    #range->
    print(range(100000000))   #range(0, 100000000)   得到可迭代对象,但此时并没有生成数据
    print(list(range(10000000000000)))    #内存错误
    print(list(range(10)))    #[0,1,2,……,9]
    
    #f=open ->
    
    
    #没有for循环,依然可以遍历
    l=[1,2,3,4]
    iterator=l.__iter__()
    while True:
        print(iterator.__next__())#虽然会报错,但是也一个个输出了   最后抛出StopIterator

     四、总结

      1.双下方法:很少直接调用的方法,一般通过其他语法触发。

      2.可迭代的——可迭代协议:含有__iter__的方法(‘__iter__' in dir(数据))

      3.可迭代的一定可以被for循环

      4.迭代器协议:含有__iter__方法和__next__方法

      5.迭代器一定可迭代,可迭代的通过调用__iter__方法可以得到一个迭代器

      6.迭代器的特点:

        1)方便使用,且只能取所有的数据取一次。下次重新取。

        2)节省内存空间(当前和取下一个数据)

  • 相关阅读:
    java.sql.SQLException: 不支持的字符集 (在类路径中添加 orai18n.jar): ZHS16GBK
    STS工具各版本下载网址
    SpringBoot访问不了JSP但却能进入后台
    springboot o.a.tomcat.util.scan.StandardJarScanner : Failed to scan [file:/D:/apache-maven-3.0.5[系统找不到指定路径]
    STS工具:mybayis连接oracle数据库
    springBoot怎样访问静态资源?+静态资源简介
    springboot注解
    8.12-14 df 、mkswap、swapon、swapoff、sync
    8.5-7 mkfs、dumpe2fs、resize2fs
    8.2-3 partprobe、tune2fs
  • 原文地址:https://www.cnblogs.com/lowislucifer/p/10993694.html
Copyright © 2020-2023  润新知