• 可迭代对象和迭代器


    可迭代对象(iterable)

    定义

    实现了__iter__方法的对象称为可迭代对象,在python中,可迭代对象有字符串、列表、元组、字典、集合等

    创建可迭代对象

    class MyNumbers:
    
        def __init__(self):
            self.a = 1
    
        def __iter__(self):
            return self
    
    my_numbers = MyNumbers()
    

    判断

    判断对象是否是可迭代对象

    from collections.abc import Iterable
    
    print(isinstance("123", Iterable))        #字符串:True
    print(isinstance([1, 2, 3], Iterable))    #列表:True
    print(isinstance((1, 2, 3), Iterable))    #元组:True
    print(isinstance({"a": 1, "b": 2}, Iterable))   #字典:True
    print(isinstance({1, 2, 3}, Iterable))    #集合:True
    print(isinstance(open("test.txt", "r"), Iterable))  #文件:True
    print(isinstance(my_numbers, "r"), Iterable))   #my_numbers对象:True
    

    也可以去源码里查看,比如源码里的list类实现了__iter__方法

    迭代器(iterator)

    定义

    实现了__iter__和__next__方法的对象称为迭代器,__iter__返回一个特殊的迭代器对象self,__next__返回下一个可用元素,如果没有元素,会抛出StopIteration异常

    内置的迭代器

    map()、zip()、enumerate()、filter()、文件对象等都是迭代器

    创建迭代器

    class MyNumbers:
    
        def __init__(self):
            self.a = 1
    
        def __iter__(self):
            return self
    
        def __next__(self):
            x = self.a
            self.a += 1
            return x
    
    my_numbers = MyNumbers()
    print(next(my_numbers))  #1
    print(next(my_numbers))  #2
    print(next(my_numbers))  #3
    

    判断

    from collections.abc import Iterator
    
    print(isinstance(my_numbers, Iterator))  #my_numbers对象:True
    

    特点

    • 迭代器是一个可以记住遍历位置的对象
    • 迭代器对象从集合的第一个元素可以访问,直到所有的元素被访问完结束
    • 迭代器只能往前不能后退
    • 迭代器有两个基本的方法:iter()和next()

    可迭代对象和迭代器的关系

    用可迭代对象创建迭代器

    可迭代对象实现了__iter__方法,但没有实现__next__方法,实际上可迭代对象调用iter()方法时,它会自动调用__iter__方法,而__iter__方法的作用是返回一个特殊的迭代器,因此实现了用可迭代对象创建迭代器

    用列表创建迭代器

    L = [1, 2, 3]
    I = iter(L)
    print(next(I))
    print(next(I))
    print(next(I))
    print(next(I))  #没有下一个元素,抛出异常
    print(next(I))
    
    
    # 运行结果
    Traceback (most recent call last):
      File "E:/virtual_workshop/everyday/test/iterators.py", line 80, in <module>
        print(next(I))
    StopIteration
    1
    2
    3
    

    为了避免异常的情况,可以使用for或者next加异常捕获来遍历元素
    for循环

    L = [1, 2, 3]
    I = iter(L)
    
    for i in I:
        print(i, end=" ")
    
    
    # 运行结果
    1 2 3
    

    next加异常捕获

    import sys
    
    L = [1, 2, 3]
    I = iter(L)
    
    while True:
        try:
            print(next(I), end=" ")
        except StopIteration:
            sys.exit()
    
    
    # 运行结果
    1 2 3
    

    用字典创建迭代器

    D = {"a":1, "b": 2, "c": 3}
    I = iter(D)
    
    for i in I:
        print(i, end=" ")
    
    
    # 运行结果
    a b c
    

    字典中有一个迭代器(但不能说字典本身就是迭代器),在迭代环境中,会自动一次返回一个key

    D = {"a":1, "b": 2, "c": 3}
    
    for key in D:
        print(key, end=" )
    
    
    # 运行结果
    a b c
    

    关系

    • 迭代器一定是可迭代的,但可迭代对象不是迭代器
    • 可以用可迭代对象创建迭代器
    • 可迭代对象必须实现__iter__方法,不能实现__next__方法
    • 可迭代对象与迭代器都有__iter__方法,但可迭代对象的__iter__用于实例化一个迭代器对象,而迭代器中的__iter__用于返回迭代器本身,与__next__共同完成迭代器的迭代

    参考文章

    《Python3 迭代器与生成器》
    《python3 迭代器》
    《Python3学习笔记(十四):可迭代对象、迭代器和生成器》
    《如何理解Python中的可迭代对象、迭代器和生成器》

  • 相关阅读:
    koa2 ctx.body 在 mysql query的回调函数中无法赋值的问题
    hibernate 实现多表连接查询
    Struts2 的国际化实现
    struts2 dwr There is no Action mapped for action ... 原因及解决方案
    Hibernate4.1配置数据库连接池 org.hibernate.service.jndi.JndiException:Unable to lookup JNDI name java:comp/env...
    Android 使用JSON格式与服务器交互 中文乱码问题解决
    Struts2 访问 Servlet API 的三种方法
    Struts2 输入校验
    hibernate4 和 spring3 整合注意事项 否则java.lang.NoSuchMethodError异常
    MySQL密码忘记的解决方案
  • 原文地址:https://www.cnblogs.com/my_captain/p/12822120.html
Copyright © 2020-2023  润新知