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

    迭代器简介:迭代是访问集合元素的一种方式。迭代器是一个可以记住遍历的位置的对象。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。

    for循环执行步骤:1.判断对象是否是可迭代的(创建对象的类要有__iter__方法)

                                  2.判断对象的__iter__方法的返回值是一个迭代器(返回值有__iter__和__next__ 方法的引用)

                                  3.每次循环调用__next__方法的返回值

    初次自定义迭代对象:

     1 class Classmate(object):
     2     def __init__(self):
     3         self.names = list()
     4 
     5     def add(self, name):
     6         self.names.append(name)
     7 
     8 
     9 classmate = Classmate()
    10 classmate.add("张三")
    11 classmate.add("李四")
    12 classmate.add("王五")
    13 
    14 for temp in classmate:
    15     print(temp)

      运行结果报错:Classmate不是可以迭代的

      说明:for循环执行首先会判断对象是否为可迭代的

    1 TypeError: 'Classmate' object is not iterable

    Classmate类中添加__iter__方法,在循环前加上判断classmate是否是可迭代:

    1     def __iter__(self):
    2         pass
    3 
    4 ......
    5 
    6 print('classmate是否是可迭代的:', isinstance(classmate, Iterable))

      运行报错:iter()返回类型为非迭代器

      说明:for循环判断为可迭代的对象后,会判断对象的iter方法的返回值是否有__iter__和__next__ 方法的引用

    1 classmate是否是可迭代的: True
    2 TypeError: iter() returned non-iterator of type 'NoneType'

    将Classmate类中的__iter__的返回值添加含__iter__ 和__next__ 方法的引用:

     1 from collections.abc import Iterable
     2 from collections.abc import Iterator
     3 
     4 
     5 class Classmate(object):
     6     def __init__(self):
     7         self.names = list()
     8 
     9     def add(self, name):
    10         self.names.append(name)
    11 
    12     def __iter__(self):
    13         # ClassIterator()相当于创建ClassIterator的对象,return这个对象相当于返回这个对象的引用
    14         return ClassIterator()
    15 
    16 
    17 class ClassIterator(object):
    18     def __iter__(self):
    19         pass
    20 
    21     def __next__(self):
    22         pass
    23 
    24 
    25 classmate = Classmate()
    26 classmate.add("张三")
    27 classmate.add("李四")
    28 classmate.add("王五")
    29 
    30 
    31 # print('classmate是否是可迭代的:', isinstance(classmate, Iterable))
    32 classmate_iterator = iter(classmate)   # iter(classmate)可以接收_iter__方法的返回值
    33 print('classmate_iterator是否是迭代器:', isinstance(classmate_iterator, Iterator))
    34 
    35 
    36 for temp in classmate:
    37     print(temp)

      运行结果:

      说明:都判断为True后开始循环取next方法的返回值

    1 True
    2 None
    3 None
    4 None
    5 None
    6 ......

    由此,通过设置next方法的返回值可以改变for循环执行的结果。如果要让for循环正确执行,next方法的返回值设置思路为:

      1.通过classmate[索引]取得classmate内的元素

      2.索引要从0到classmate的元素长度减1,且调用一次next,索引加1

      3.通过raise StopIteration 抛出StopIteration异常告诉for循环已经循环结束。此时索引是大于等于classmate元素的长度

    for循环要正确执行代码修改如下:

     1 class Classmate(object):
     2     def __init__(self):
     3         self.names = list()
     4 
     5     def add(self, name):
     6         self.names.append(name)
     7 
     8     def __iter__(self):
     9         # ClassIterator()相当于创建ClassIterator的对象,return这个对象相当于返回这个对象的引用
    10         # ClassIterator(self)将自己作为实参传递到ClassIterator这个类
    11         # 当ClassIterator类的init方法用 self.名称=形参 时,ClassIterator类的 self.名称 将指向我自己
    12         return ClassIterator(self)
    13 
    14 
    15 class ClassIterator(object):
    16 
    17     def __init__(self, obj):
    18         self.obj = obj
    19         self.num = 0
    20 
    21     def __iter__(self):
    22         pass
    23 
    24     def __next__(self):
    25         if self.num < len(self.obj.names):
    26             rest = self.obj.names[self.num]
    27             self.num += 1
    28             return rest
    29         else:
    30             raise StopIteration
    31 
    32 
    33 classmate = Classmate()
    34 classmate.add("张三")
    35 classmate.add("李四")
    36 classmate.add("王五")
    37 
    38 
    39 # print('classmate是否是可迭代的:', isinstance(classmate, Iterable))
    40 # classmate_iterator = iter(classmate)
    41 # print('classmate_iterator是否是迭代器:', isinstance(classmate_iterator, Iterator))
    42 
    43 
    44 for temp in classmate:
    45     print(temp)

      运行结果:

    1 张三
    2 李四
    3 王五

    可以将Classmate类里面的__iter__方法的返回值设置成自己(self),那么在Classmate类里面添加__next__方法并设置返回值也可以将对象的__iter__方法的返回值设置为一个迭代器,这样精简了代码:

     1 class Classmate(object):
     2     def __init__(self):
     3         self.names = list()
     4 
     5     def add(self, name):
     6         self.names.append(name)
     7         self.num = 0
     8 
     9     def __iter__(self):
    10         return self
    11 
    12     def __next__(self):
    13         if self.num < len(self.names):
    14             rest = self.names[self.num]
    15             self.num += 1
    16             return rest
    17         else:
    18             raise StopIteration
    19 
    20 
    21 classmate = Classmate()
    22 classmate.add("张三")
    23 classmate.add("李四")
    24 classmate.add("王五")
    25 
    26 for temp in classmate:
    27     print(temp)

      运行结果:

    1 张三
    2 李四
    3 王五
  • 相关阅读:
    sockjs-node/info?t=报错解决
    微信昵称表情符号前端显示问题
    vue-cli 3.0项目安装报错
    vue-cli项目按需引入element-ui实际操作
    javafx分别设置四个边框
    springmvc使用<mvc:default-servlet-handler/>导致的handler失效
    windows注册表删除右键菜单
    计算机实现32位整数加减乘除的方法
    常用排序算法
    AbstractCollection类中的 T[] toArray(T[] a)方法源码解读
  • 原文地址:https://www.cnblogs.com/zzmx0/p/12670237.html
Copyright © 2011-2022 走看看