zoukankan      html  css  js  c++  java
  • 可迭代对象和迭代器

    可迭代对象和迭代器

    一、迭代器的概念

    迭代器即迭代的工具,那什么是迭代呢?
    迭代是一个重复的过程,每次重复即一次迭代,并且每次迭代的结果都是下一次迭代的初始值

    while True: #只是单纯地重复,因而不是迭代
        print('===>') 
        
    l=[1,2,3]
    count=0
    while count < len(l): #迭代
        print(l[count])
        count+=1
    

    二、可迭代对象

    python中一切皆对象,对于这一切的对象中,但凡有__iter__方法的对象,都是可迭代对象。

    基于上一次的结果推出下一次结果

    # 
    
    # 可迭代(具有__iter__方法)对象
    
    x = 2  # 不可迭代
    # x.__iter__  # SyntaxError: invalid syntax
    
    s = 'randysun'
    s.__iter__()  # str 为可迭代对象 <str_iterator object at 0x035B4D70>
    
    lt = [1, 2, 3]
    lt.__iter__()  # list 为可迭代对象
    
    dic = {'a': 1, "b": 2}
    dic.__iter__()  # dict 为可迭代对象
    
    tup = (1,)
    tup.__iter__()  # tuple 为可迭代对象
    
    se = {1, 2, 3}
    se.__iter__()  # 可迭代对象
    
    f = open('test.py')  
    f.__iter__()  # 可迭代对象
    
    def func():
        pass     # 不可迭代对象
    
    # 有__iter__()方法的对象都是可迭代对象,然后除了数字类型和函数之外都是可迭代对象
    

    可迭代的对象:Python内置str、list、tuple、dict、set、file都是可迭代对象,除了数字类型外。

    s = 'randysun'
    
    s_iter = s.__iter__()
    print(s_iter.__next__())
    print(s_iter.__next__())
    print(s_iter.__next__())
    

    特点:内置有__iter__方法的都叫可迭代的对象。(可以理解为可以for循环打印)

    [49迭代器-装逼.jpg?x-oss-process=style/watermark

    二、迭代器对象

    只有字符串和列表、元组都是依赖索引取值的,而其他的可迭代对象都是无法依赖索引取值的。因此我们得找到一个方法能让其他的可迭代对象不依赖索引取值。

    迭代器对象: 具有__iter__以及__next__方法的叫做迭代器对象,只有文件是迭代器对象

    s = 'randy'  # 可迭代对象,不属于迭代器对象
    s.__iter__()
    lt = [1, 2, 3]  # 可迭代对象,不属于迭代器对象
    dic = {'a': 1, 'b': 2}  # 可迭代对象,不属于迭代器对象
    tup = (1,)  # 元组只有一个元素必须得加逗号# 可迭代对象,不属于迭代器对象
    se = {1, 2, 3}  # 可迭代对象,不属于迭代器对象
    f = open('time.py')  # 可迭代对象,迭代器对象
    
    # 只有文件是迭代器对象
    
    

    通过迭代对象和迭代器实现遍历列表

    # 不依赖索引取值 for循环原理
    lt = [1, 2, 3]
    lt_iter = lt.__iter__()
    while True:
        try:
            print(lt_iter.__next__())
        except StopIteration:
            break
    

    1
    2
    3

    for i in lt:  # 可迭代对象;迭代器对象 不依赖索引取值,而是迭代取值
        print(i)
    # 1. 首先使用__iter__把lt变成迭代器对象,对文文件也要使用iter方法把文件再一次iter
    # 2. 然后使用__next__方法进行迭代取值
    # 3. 判断StopIteration异常,遇到异常终止
    

    三、for循环原理

    for循环称为迭代器循环,in后必须是可迭代的对象。

    lis = [1, 2, 3]
    for i in lis:
        print(i)
    
    

    1
    2
    3

    因为迭代器使用__iter__后还是迭代器本身,因此for循环不用考虑in后的对象是可迭代对象还是迭代器对象。

    由于对可迭代对象使用__iter__方法后变成一个迭代器对象,这个迭代器对象只是占用了一小块内存空间,他只有使用__next__后才会吐出一个一个值。如lis = [1,2,3,4,5,...]相当于一个一个鸡蛋,而lis = [1,2,3,4,5,...].__iter__相当于一只老母鸡,如果你需要蛋,只需要__next__即可。

    Python2中

    print(range(10))  # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    

    Python3中

    print(range(10))  # range(0, 10)
    

    四、总结

    • 可迭代对象:具有__iter__方法的对象就是可迭代对象,除了数字类型和函数都是可迭代对象

    • 可迭代器对象:具有__iter__和__next__方法的都是迭代器对象,只有文件

    • 迭代器对象一定是可迭代对象,可迭代对象不一定是可迭代器对象

    • for循环 == 迭代循环

      1. 把lt(可迭代对象/迭代器对象)用__iter__方法转换成迭代器对象
      2. 使用__next__取出迭代器里的所有值
      3. 使用__next__方法取尽迭代器中的所有值,一定会报错,通过异常捕捉退出while循环
      4. 解决了不依赖索引取值
    • 优缺点

    1. 优点:

      • 提供一种统一的、不依赖于索引的迭代方式
      • 惰性计算,节省内存
    2. 缺点:

      • 无法获取长度(只有在next完毕才知道到底有几个值)
      • 一次性的,只能往后走,不能往前退,取值麻烦,只能一个一个取,并且只能往后取,值取了就没了
    在当下的阶段,必将由程序员来主导,甚至比以往更甚。
  • 相关阅读:
    通过IDEA解决spring配置文件
    idea中xml打开方式变成file,改回来
    idea 搜索不到前端的ajax controller接口的原因
    IDEA 出现 updating indices 卡进度条问题的解决方案并加快索引速度
    java 循环中使用list时,出现list中全部加入了对象导致没有实现分组的解决方案
    java 从字符串中 以单个或多个空格进行分隔 提取字符串
    idea ssm项目出现日志中文乱码,封装的json中的msg字段中文乱码(但是json封装的bean中的字段不乱码)等其他各种项目下的中文乱码解决方案
    javaweb 解决jsp中${}传递中文值到后端以及get请求中文乱码的问题
    idea 开发javaee 时,出现访问的文件和源文件不一样,没有正常更新的解决方案
    java 迭代器只遍历了一次的解决方案
  • 原文地址:https://www.cnblogs.com/randysun/p/11341123.html
Copyright © 2011-2022 走看看