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

    迭代是Python最强大的功能之一,是访问集合元素的一种方式。

    迭代器是一个可以记住遍历的位置的对象。

    迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。

    迭代器有两个基本的方法:iter() 和 next()

    字符串,列表或元组对象都可用于创建迭代器:

    参考:https://www.cnblogs.com/chichung/p/9537969.html

    一、定义

    1.1 迭代

    我们知道可以对list,tuple,dict,str等数据类型使用for...in的循环语法,从其中依次取出数据,这个过程叫做遍历,也叫迭代

    迭代是访问集合元素的一种常用的方式。

    1.2迭代对象

    简单来说,可以用for...in循环语句,从其中依次取出数据的对象,就是可迭代对象

    例如,列表、元组、字典、字符串都是可迭代对象。整数、浮点数、布尔值都是不可迭代的。

    1.3 迭代器

    迭代器是一个可以记住遍历的位置的对象。

    迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。

    在可迭代对象进行迭代的时候,即用for...in...循环语法依次取出数据时,过程是怎样的呢?

    我们发现,每迭代一次(即在for...in...中每循环一次)都会返回对象中的下一条数据,一直向后读取数据直到迭代了所有数据后结束。

    那么,在这个过程中就应该有一个“人”去记录每次访问到了第几条数据,以便每次迭代都可以返回下一条数据。我们把这个能帮助我们进行数据迭代的“人”称为迭代器(Iterator)

    举个栗子,老师安排一个班的同学每节课上课前进行演讲,按学号顺序进行,A同学这节课演讲,老师就会记住这节课是A同学演讲,那么下节课就是B同学进行演讲...依次类推,在这个例子里,老师就是一个迭代器。

     二、 操作

    2.1  判断一个对象是否可以迭代

    isinstance(object,classinfo)内置函数可以判断一个对象是否是一个已知的类型,类似 type()。

    • object -- 实例对象。
    • classinfo -- 可以是直接或间接类名、基本类型或者由它们组成的元组。
    from collections.abc import Iterable
    
    print(isinstance([1, 2, 3], Iterable))
    print(isinstance((1,2,3), Iterable))
    print(isinstance({"name": "chichung", "age": 23}, Iterable))
    print(isinstance("sex", Iterable))
    print(isinstance(123, Iterable))
    print(isinstance(True, Iterable))
    print(isinstance(1.23, Iterable))

     2.2 获取可迭代对象的迭代器

    list = [1,2,3,4,5]  # list是可迭代对象
    lterator = iter(list)  # 通过iter()方法取得list的迭代器
    print(lterator)
    
    输出:
    <list_iterator object at 0x7f35e6537a20>

    迭代器是获取到了,那么应该怎样用呢?

    next()函数是通过迭代器获取下一个位置的值。

    注意: 当我们已经迭代完最后一个数据之后,再次调用next()函数会抛出StopIteration的异常,来告诉我们所有数据都已迭代完成,不用再执行next()函数了。

    from collections.abc import Iterable
    
    list = [1,2,3,4,5,6]  # list是可迭代对象
    lterator_1 = iter(list)  # 通过iter()方法取得list的迭代器
    print(next(lterator_1))  # 1
    print(next(lterator_1))  # 2
    print(next(lterator_1))  # 3
    print(next(lterator_1))  # 4
    print(next(lterator_1))  # 5
    print(next(lterator_1))  # 6 
    print(next(lterator_1))

    2.3 可迭代对象如何获取迭代器

    可迭代对象其实都是collections模块里的Iterable类创建出来的实例的。

    你写一个列表,以为他不是任何类创建的,只是单纯一个列表?不是的,其实它就是Iterable类创建的实例对象。

    点进Iterable的类看一下,你会发现新大陆。

    class Iterable(metaclass=ABCMeta):
    
        __slots__ = ()
    
        @abstractmethod
        def __iter__(self):  # 注意点
            while False:
                yield None

    原来由Iterable创建的对象,是有一个魔方方法__iter__(self)的。这个方法就是返回一个迭代器的。所以,由Iterable类创建的实例对象,是可以拿出一个迭代器的。

    接下来要说的有点绕......

    之所以Iterable类创建的对象是可迭代对象,是因为Iterable类有这个方法!不信?我就来编写一个能创建可迭代对象的类

    import collections
    
    class BecomeIterable:
    
        def __iter__(self):
            """返回一个空的迭代器"""
            return None
    
    people = BecomeIterable()
    print(isinstance(people, collections.Iterable))
    
    输出:
    True

    2.4.迭代器为什么能用next()函数进行迭代?

    我们知道,可以用iter()函数,在可迭代对象中获取迭代器。例如:iterator = iter([1,2,3])

    这样一看,迭代器也就是一个对象而已啊,为什么他可以用next()函数,一下子出来一个值,一下子又出来一个值。

    其实是这样的,iter()函数能调用可迭代对象的魔方方法__iter__(),从而返回一个迭代器。怎么返回的呢?__iter__()方法是使用collections模块里的Iterator类来创建一个迭代器对象。

    接下来看下Iterator的一部分源代码:

    class Iterator(Iterable):
    
        __slots__ = ()
    
        @abstractmethod
        def __next__(self):
            'Return the next item from the iterator. When exhausted, raise StopIteration'
            raise StopIteration
    
        def __iter__(self):
            return self

    稍微注意下魔方方法__next__()的最后一句,如果超出迭代方位就抛出StopIteration异常。

    还有一点需要注意,迭代器的源代码也有__iter__()魔方方法,所以,Iterator也是一个可迭代对象呀!!!

    所以,如果你喜欢在迭代器里面再取出迭代器也是可以的,但是好像有点无聊......目前还不知道有什么应用到......

  • 相关阅读:
    项目外部 property文件使用方法
    java JsonArray统一添加key
    java发送Http请求
    excel数据追加,java实现
    request.getParameter("name")获取参数为null和""空字符串的区别
    maven 配置jetty插件启动 及简单测试
    左右值编码实现树状存储
    Spring将classpath下的 .properties文件数据读出放到map中,在初始化时加载
    Ubuntu简单配置
    java.io.Serializable浅析
  • 原文地址:https://www.cnblogs.com/qianslup/p/12009534.html
Copyright © 2011-2022 走看看