zoukankan      html  css  js  c++  java
  • python当中的 可迭代对象 迭代器

    学习python有一段时间了,在学习过程中遇到很多难理解的东西,做一下总结,希望能对其他朋友有一些帮助。

    完全是个人理解,难免有错,欢迎其他大神朋友们批评指正。

     

     

    1 迭代

       什么是迭代呢??我们可以这样理解,一个容器类型的数据,比如 列表[ ]  、元组 () 和 字典 { }, 我们可以把这样类型的数据放入for temp in [1,2,3] 当中,temp 被一次一次的赋值成为后面容器内数据,然后我们拿到temp进行一些想做的事情。那么for 循环中自动的帮我们把数据一次一次的取出来,可以理解成,这样的操作就是迭代。

     

    2 可迭代对象

      在python当中有有那么一些特定的数据类型,可以放入for in 循环当中,这样的数据类型,我们可以说他们是可迭代对象。

      我们可以用 isinstance方法来检测一个对象是不是可迭代对象。

      可迭代对象可以放入for in中迭代,也可以放入list() tuple()等帮我们快速生成一个数据。

    上代码!

    1 from collections import Iterable
    2 
    3 print( isinstance( [] , Iterable )  )  #True
    4 print( isinstance( {} , Iterable )  ) #True
    5 print( isinstance( () , Iterable )  )  #True
    6 print( isinstance( 1 , Iterable )  )  #False

    从中我们可以看出来,列表、元组、字典都是可迭代对象。而整型数据不是可迭代对象。

     

    可迭代对象的实质是怎么回事呢???? (一脸懵逼)

      其实,可迭代对象的内部必须实现一个方法,__iter__()方法,这个方法的功能是,返回一个迭代器,这个迭代器是帮助自己进行迭代的。实现这个方法的对象,python就认为它是可迭代对象。

    迭代器又是啥???(二脸懵逼)不要着急 稍后我再分享

    上代码!!先看一看可迭代对象:

     

     

     

    1 from collections import Iterable
    2 #我们自己创建一个类 里面实现iter方法 python就认为它的对象是可迭代对象了
    3 class MyIterableObj(object):
    4     def __iter__(self):
    5         pass
    6 
    7 demo1 = MyIterableObj()
    8 print(isinstance( demo1 , Iterable ))       #True

     

     

     

    从中可以看出来,我们自己写一个类,里面实现了iter方法,即使什么都没有做,创建一个对象之后,判断一下 python就认为这个对象是一个可迭代对象了。

     

    3 迭代器

      刚刚我们说了,可迭代对象里面的iter方法返回一个帮助自己迭代的迭代器。迭代器是什么呢??

      其实我也不知道!(嘻嘻 笑哭) 开玩笑的啦~~~

      在我的理解当中呢,迭代器是帮助可迭代对象一个一个把里面元素取出来的一个对象。迭代器类型的对象都是可迭代对象,为什么呢,我们来看一看实质。

    迭代器的实质:  

      迭代器内部必须实现两个方法: __iter__() 和 __next__()

      __iter__() 功能是返回一个迭代器,帮助我们自己这种类型进行迭代,因为自己就是迭代器,所以迭代器中的__iter__() 返回的是self自己

      __next__() 功能是:  简单的说就是返回当前元素的,就像列表当中,取出第一个元素,再调用next的时候就取出了第二个元素。 但是在for循环当中放入列表的时候,for是怎么知道列表最后一个元素都已经取完了呢????(我的天啊!不知道啊!!呜呜!!!)别着急,继续往下看

         复杂的说, next会做两件事:1 如果当前数据没有超出范围,这次当前值返回,然后自己进行标记,找到下一个要返回的值。

                       2 如果当前迭代器上次取出了最后一个元素,这一次当前数据是在范围之外的,那么就抛出异常(StopIteration),告诉for循环等一些内建工具,迭代结束了。

      不是很理解??没关系,上代码我们来看看!!

    我们先看一看 python中认为什么样的东西是迭代器:

    from collections import Iterator
    print( isinstance( [] , Iterator ) )    #False 很显然,可迭代对象不是迭代器
    print( isinstance( [].__iter__() , Iterator ) )    #True 这是调用了可迭代对象的iter方法得到一个迭代器对象
    #在python中 内建了 iter() 方法和 next() 方法,把对象传进去与__iter__ 和 __next__ 相同功能
    print( isinstance( iter([]) , Iterator ) )  #True
    
    # 像我说的 我们自己实现一个迭代器
    class MyIterator(object):
        def __iter__(self):
            pass
        def __next__(self):
            pass
    
    demo2 = MyIterator()
    print( isinstance(demo2 , Iterator ) )      # True

     

    看的出来,我们自己的类对象里面只要具有这两个方法 python就认为他是迭代器了。

      大家还记不记得我说过,迭代器都是可迭代对象,  因为迭代器一定有__iter__方法,所以它一定是迭代对象

     

    ok!接下来呢,我们把两个函数的业务逻辑补全,看一看迭代器两个方法实际上在干什么??

    我们来实现一个 传入一个n 给我们迭代出 0到n 的迭代器  这个功能就好像是 range(n) 一样 我们自己实现一下!

     1 '''
     2 接下来,我们具体实现一个能够完成功能, 能够放入for循环遍历的迭代器!! 啊好刺激啊!!
     3 我们要实现的业务是: 传入一个参数n , 我们要迭代出 0到n的数
     4 '''
     5 class NumIterator(object):
     6     #初始化我们接收一个参数n  告诉我们迭代到多少结束
     7     def __init__(self , n):
     8         self.n = n
     9         #我们实际上是把 i 交给函数调用者
    10         self.i = 0
    11     # iter方法 返回一个迭代器,自己就是迭代器 所以返回自己
    12     def __iter__(self):
    13         return self
    14     # next方法 判断是否越界 如果不越界返回一个元素  如果越界了抛出异常
    15     def __next__(self):
    16         #如果 没有越界, 我们返回给调用者迭代结果,并且自己记录下一次迭代的位置
    17         if self.i <= self.n:
    18             res = self.i
    19             self.i += 1
    20             return res
    21         # 进入else说明i已经超过n 迭代越界了 抛出异常告诉for循环 迭代结束了
    22         else:
    23             #如果不抛出这个异常,for循环不知道什么时候停止迭代 会不停的调用next 陷入死循环
    24             raise StopIteration
    25 
    26 #一个前3的自然数的迭代器对象
    27 demo3 = NumIterator(3)
    28 # 之前说过, 我们可以调用python内建的next方法来获取迭代器的元素
    29 print( next(demo3) )    # 0
    30 print( next(demo3) )    # 1
    31 print( next(demo3) )    # 2
    32 print( next(demo3) )    # 3
    33 #print( next(demo3) )    # 这时候再调用会抛出异常 因为越界了!
    34 
    35 #同样我们自己写的迭代器能够放入for循环当中
    36 demo4 = NumIterator(10)
    37 for num in demo4 :
    38     print(num)
    39 #我们发现,会打印出从0 到 10  然后for循环就停了

    看完上面的代码,我来解释一下 其实for循环的实质:

      for 不知道我们放在in后面的是可迭代对象还是迭代器,他会先调用iter方法拿到一个迭代器,然后不停的调用next方法取到值,然后提供给我们,一直到取某个值的时候接收到了一个StopIteration异常,for循环就终止了。

     

    ok!! 到这里呢,可迭代对象、迭代器的知识就跟大家分享完了。

     

    不知道小伙伴们都有没有理解,希望对一些不理解这些深层次东西的同学有一些帮助!!

    欢迎大家批评指正~~~~谢谢大家的参考!

    我是稀里糊涂的林老冷~

  • 相关阅读:
    图形化编程娱乐于教,Kittenblock arduino实例解读,红外线接收
    图形化编程娱乐于教,Kittenblock arduino实例解读,红外线发送
    图形化编程娱乐于教,Kittenblock arduino实例解读,红外线发送
    图形化编程娱乐于教,Kittenblock arduino实例解读,红外线发送
    图形化编程娱乐于教,Kittenblock arduino实例,液晶屏显示
    图形化编程娱乐于教,Kittenblock arduino实例,数码管计时器
    图形化编程娱乐于教,Kittenblock arduino实例,超声波测距
    超级简单的Android Studio jni 实现(无需命令行)
    实现ViewPager懒加载的三种方法
    MySQL安装
  • 原文地址:https://www.cnblogs.com/Lin-Yi/p/7295696.html
Copyright © 2011-2022 走看看