〖Python零基础入门篇(61)〗- Python 中的迭代器

万叶集
🎉 隐约雷鸣,阴霾天空。 🎉
🎉 但盼风雨来,能留你在此。 🎉

前言
✌ 作者简介:渴望力量的哈士奇 ✌,大家可以叫我 🐶哈士奇🐶 ,一位致力于 TFS 赋能的博主 ✌
🏆 CSDN博客专家认证、新星计划第三季全栈赛道 top_1 、华为云享专家、阿里云专家博主 🏆
📫 如果文章知识点有错误的地方,请指正!和大家一起学习,一起进步👀
💬 人生格言:优于别人,并不高贵,真正的高贵应该是优于过去的自己。💬
🔥 如果感觉博主的文章还不错的话,还请👍关注、点赞、收藏三连支持👍一下博主哦


专栏系列(点击解锁) 学习路线指引 知识定位
🔥Python全栈白皮书🔥 零基础入门篇 以浅显易懂的方式轻松入门,让你彻底爱上Python的魅力。
语法进阶篇 主要围绕多线程编程、正则表达式学习、含贴近实战的项目练习 。
自动化办公篇 实现日常办公软件的自动化操作,节省时间、提高办公效率。
自动化测试实战篇 从实战的角度出发,先人一步,快速转型测试开发工程师。
数据库开发实战篇 更新中
爬虫入门与实战 更新中
数据分析篇 更新中
前端入门+flask 全栈篇 更新中
django+vue全栈篇 更新中
拓展-人工智能入门 更新中
网络安全之路 踩坑篇 记录学习及演练过程中遇到的坑,便于后来居上者
网安知识扫盲篇 三天打鱼,不深入了解原理,只会让你成为脚本小子。
vulhub靶场漏洞复现 让漏洞复现变得简单,让安全研究者更加专注于漏洞原理本身。
shell编程篇 不涉及linux基础,最终案例会偏向于安全加固方向。 [待完结]
WEB漏洞攻防篇 2021年9月3日停止更新,转战先知社区等安全社区及小密圈
渗透工具使用集锦 2021年9月3日停止更新,转战先知社区等安全社区及小密圈
点点点工程师 测试神器 – Charles 软件测试数据包抓包分析神器
测试神器 – Fiddler 一文学会 fiddle ,学不会倒立吃翔,稀得!
测试神器 – Jmeter 不仅是性能测试神器,更可用于搭建轻量级接口自动化测试框架。
RobotFrameWork Python实现的自动化测试利器,该篇章仅介绍UI自动化部分。
Java实现UI自动化 文档写于2016年,Java实现的UI自动化,仍有借鉴意义。
MonkeyRunner 该工具目前的应用场景已不多,文档已删,为了排版好看才留着。


文章目录

  • 什么是迭代器
  • 如何生成迭代器
  • 迭代器函数 – iter() 函数 与 next() 函数
  • 可迭代的对象
  • 生成迭代器
  • 迭代器的用法 – 演示案例
  • 什么是迭代器

    迭代是 python 中访问集合元素的一种非常强大的一种方式。迭代器是一个可以记住遍历位置的对象,因此不会像列表那样一次性全部生成,而是可以等到用的时候才生成,因此节省了大量的内存资源。迭代器对象从集合中的第一个元素开始访问,直到所有的元素被访问完。迭代器有两个方法:iter()next()方法。

    这么解释可能不太直观,我们以生活的一个小栗子来解释一下,方便大家能够更深刻的理解。比如说我们去超市买水果,而正巧超市的服务人员正在摆放苹果。服务人员告诉我们需要等苹果都摆放完毕我们才可以拿苹果,这样就很耽误我们的时间。(这个场景中,柜台上其实已经有苹果了,只不过销售不让拿罢了。)

    然后我们再去卖橘子的柜台,服务人员也在摆放橘子。但是服务人员告诉我们可以不用等他摆放完毕,我们可以直接拿橘子,这样就会很好的节省我们的时间。如果我们拿橘子的速度超过了服务人员摆放的速度 ,我们只需要等待服务人员摆放之后就可以直接拿橘子,大大的提升了我们买橘子的效率。

    而迭代器就类似于我们买橘子的场景,我们平时的程序都是一次性写入到内存中。比如我们的列表中存在成百上千的数据,都是一次性写入到内存里的,通过这样让我们来使用。但是迭代器却是按需加载,有一点内容就会放在内容里面,我们就可以立刻使用内存中的数据进行我们的逻辑处理。这样就不要所有的数据都写入到内存中就可以使用,大大的提升了使用效率。

    如何生成迭代器

    迭代器函数 – iter() 函数 与 next() 函数

        iter(iterable)从可迭代对象中返回一个迭代器,iterable必须是能提供一个迭代器的对象
        next(iterator) 从迭代器iterator中获取下一了记录,如果无法获取下一条记录,则触发stoptrerator异常
        说明:
            1.迭代器只能往前取值,不会后退
            2.用iter函数可以返回一个可迭代对象的迭代器
        示例:
    

    iter()函数介绍:生成一个迭代器对象

    iter()函数用法:iter(iterable)

    参数介绍:iterable —> 可迭代的数据类型(比如列表、字典、元组以及集合类型等)

    示例:iter([1, 2, 3])

    返回值:<list_iterator at 0x4f3bff0>


    next()函数介绍:返回迭代器中的数据

    next()函数用法:next(iterable)

    参数介绍:iterable —> 迭代器对象

    示例:

    iter_obj = iter([1,2,3])
    next(iter_obj)
    

    返回值:

    # >>> 1,2,3
    # >>> StopIteration
    

    综上,我们得出结论:

    iter(iterable)从可迭代对象中返回一个迭代器,iterable必须是能提供一个迭代器的对象
    next(iterable) 从迭代器iterator中获取下一了记录,如果无法获取下一条记录,则触发stoptrerator异常

    演示案例如下:

    # coding:utf-8
    
    
    test_list = [1, 3, 5, 7]
    test_iter = iter(test_list)     # 让test_list提供一个能访问自己的迭代器
    print(next(test_iter))     # 1  从迭代器中取值,让迭代器去获取l中的一个元素
    print(next(test_iter))     # 3
    print(next(test_iter))     # 5
    print(next(test_iter))     # 7
    print(next(test_iter))     # StopIterable 异常
    

    test_list 实际上是一个列表,但是被迭代器迭代之后。并不是一次性将列表放入内存中,而是每次放一个元素进入内存,然后被读取。(这就是我们说的按需加载)


    可迭代的对象

    类似于list、tuple、str 等类型的数据可以使用for… in… 的循环遍历语法可以从其中依次拿到数据并进行使用,我们把这个过程称为遍历,也称迭代。python中可迭代的对象有list(列表)、tuple(元组)、dirt(字典)、str(字符串)set(集合)等。

    示例如下:

    test_list = [1,2,3,4,5]
    test_dirt = {
        "name":"张三",
        "sex":"男",
        "age":33
        }
        
    test_tuple = (1,2,3,4,5)
    test_set = {1,2,3,3,4}
     
        
    for i in test_list:
        print(i)
     
    for i in test_dirt:
        print(i)
     
    for i in test_tuple:
        print(i)
     
    for i,j in test_set.items():
        print("%s:%s" % (i,j))
        
    # >>> 执行结果如下:
    # >>> test_list的元素为: 1
    # >>> test_list的元素为: 2
    # >>> test_list的元素为: 3
    # >>> test_list的元素为: 4
    # >>> test_list的元素为: 5
    # >>> test_dirt的元素为: name
    # >>> test_dirt的元素为: sex
    # >>> test_dirt的元素为: age
    # >>> test_tuple的元素为: 1
    # >>> test_tuple的元素为: 2
    # >>> test_tuple的元素为: 3
    # >>> test_tuple的元素为: 4
    # >>> test_tuple的元素为: 5
    # >>> test_set的元素为:1
    # >>> test_set的元素为:2
    # >>> test_set的元素为:3
    # >>> test_set的元素为:4
    

    生成迭代器

    除了刚刚我们使用的 iter() 函数之外 ,我们还有其他方法生成迭代器:

    第一种:for循环生成方法 —> 我们可以在函数中使用 for 循环, 并对每一个 for 循环的成员使用 yield() 函数 [它的意思就是将每一个 for 循环成员放到一个迭代器对象中,不过只有被调用才会被放入。]

    示例如下:

    def test():
        for i in range(10):
            yield i
    
    
    result = test()
    
    print('for 循环,第一次 \'i\'的值为:', next(result))
    print('for 循环,第二次 \'i\'的值为:', next(result))
    print('for 循环,第三次 \'i\'的值为:', next(result))
    print('for 循环,第四次 \'i\'的值为:', next(result))
    
    # >>> 执行结果如下:
    # >>> for 循环,第一次 'i'的值为: 0
    # >>> for 循环,第二次 'i'的值为: 1
    # >>> for 循环,第三次 'i'的值为: 2
    # >>> for 循环,第四次 'i'的值为: 3
    

    注意:超过10次异常会抛 StopIteration 的异常。


    第二种:for 循环一行生成迭代器对象。

    示例如下:

    result = (i for i in [1, 2, 3])		# 将 for 循环在非函数中 赋值 给一个变量, 这也是生成一个迭代器变量的方法  
    
    print('for 循环,第一次 \'i\'的值为:', next(result))		# 使用 next 调用迭代器
    print('for 循环,第二次 \'i\'的值为:', next(result))
    print('for 循环,第三次 \'i\'的值为:', next(result))
    
    # >>> for 循环,第一次 'i'的值为: 1
    # >>> for 循环,第二次 'i'的值为: 2
    # >>> for 循环,第三次 'i'的值为: 3
    

    注意: next(result) 超过4次会抛 StopIteration 的异常。

    划重点:

    使用 for 循环生成的迭代器,可以不使用 next() 函数 也可以执行,(依然可以通过 for 循环 获取迭代器的数据)不仅如此,当我们调取完迭代器中的数据之后,程序不会抛出异常,相比较与 next() 函数要友好的多。

    示例如下:

    result = (i for i in [1, 2, 3])
    
    for item in result:
        print(item)
        
    # >>> 执行结果如下:
    # >>> 1
    # >>> 2
    # >>> 3
    
    # 循环结束,程序正常退出,不会抛出 StopIteration 的异常
    

    迭代器的用法 – 演示案例

    案例一:

    def make_iter():
        for i in range(5):
            yield i
    
    iter_obj = make_iter()
    
    for i in iter_obj:
        print(i)
    print('----')
    for i in iter_obj:
        print(i)
        
    # >>> 执行结果如下:
    # >>> 0
    # >>> 1
    # >>> 2
    # >>> 3
    # >>> 4
    # >>> ----
    
    # >>> 从运行结果得出结论,当我们从内存中读取完迭代器所有的值后,内存就会被释放,不再循环输出。
    

    案例二:

    iter_obj = (i for i in range(4))
    
    for i in iter_obj:
        print(i)
    print('=====')
    for i in iter_obj:
        print(i)
    
    # >>> 执行结果如下:
    # >>> 0
    # >>> 1
    # >>> 2
    # >>> 3
    # >>> =====
    # >>> 从运行结果得出结论,当我们从内存中读取完迭代器所有的值后,内存就会被释放,不再循环输出。
    

    迭代器 除了前文我们提到的 按需加载 ,可以提升我们的执行速度以外。

    还有另外一个原因,试想一下:如果我们的列表只有10个数据,那么读取的速度会很快。可能对资源(也就是我们的内存)占用的消耗不是很大;如果我们有一个成千上万甚至十万数据的列表,那么这些数据都要一次性的写入内存里,这么多的数据所消耗占用的资源必然会很大,甚至会撑爆我们的内存造成内存溢出,程序就会报错了。

    所以如果通过迭代器的方式,我们只需要用到一个数据就将一个数据扔到内存里并且被使用。这样既可以提高我们内存使用的效率,又可以减少我们内存的消耗。这也是我们平时使用迭代器的目的。

    来源:全栈哈士奇

    物联沃分享整理
    物联沃-IOTWORD物联网 » 〖Python零基础入门篇(61)〗- Python 中的迭代器

    发表评论