当前位置: 首页 > news >正文

python之迭代器

python之迭代器

文章目录

  • python之迭代器
    • 一、迭代器介绍
      • 什么是迭代器?
        • 代码示例
      • 为何要用迭代器
        • 区分迭代与单纯的重复:
      • 如何用迭代器
    • 二、可迭代对象
      • 什么是可迭代对象?
    • 三、迭代器对象
      • 什么是迭代器对象?
      • 如何得到迭代器对象?
      • 示例:
      • 总结:
    • 四、for循环原理
      • `for`循环与`while`循环
      • for 循环低层原理:
      • 示例:
    • 五、总结
      • 可迭代对象与迭代器对象之间的关系
        • 可迭代对象:
          • 示例:
        • 迭代器对象:
      • 迭代器的优缺点
        • 优点:
        • 缺点:

一、迭代器介绍

什么是迭代器?

迭代器指的是用来迭代取值的工具, 迭代就是一个重复的过程, 每次重复都是基于上一次的结果而进行的. 单纯的重复并不是迭代.

代码示例

count =1
while count <5:
    print(count)
    count +=1

l=[11,22,333,44,555]
def get_item(l):
    count=0
    while count <len(l):
        print(l[count])
        count+=1

为何要用迭代器

迭代器是用来取值的工具,而涉及到把多个值循环取出来的类型有:列表, 字符串, 元组, 字典, 集合, 打开的文件

  1. 为了找到一种通用的取值方案
  2. 为了节省内存

区分迭代与单纯的重复:

单纯的重复:

while True:
    msg = input(">>>:").strip()
    print(msg)

迭代取值:

需求:使用whlie循环打印出列表中的每项元素的值

# 需求: 使用while循环打印列表中的每项元素的值
# while循环是一个重复的过程, 且每次重复都是基于上一次的index累加操作之后的结果而继续的, 所以这是一个迭代现象.
goods = ['mac', 'lenovo', 'acer', 'dell', 'sony']
index = 0
while index < len(goods):
    print(goods[index], end=' ')   # mac lenovo acer dell sony 
    index += 1

如何用迭代器

内置有__iter__方法的类型都称之为可迭代的对象
但凡调用了__iter__方法,就会将该类转换成迭代器对象
比如res=.__iter__()

二、可迭代对象

什么是可迭代对象?

可迭代对象:iterable

可迭代对象就是可以转换为迭代器的对象

从语法层面上讲,内置有__iter__()方法的的对象, 内置可以iter()的对象,字符串、列表、元组、字典、集合、打开的文件都是可迭代对象

 "hello".__iter__
 [].__iter__
 (11,).__iter__
 {"k1":111}.__iter__
 {11,22}.__iter__
 f=open("a.txt",mode='wt')  # 文件本身就是迭代器对象
 f.__iter__

三、迭代器对象

什么是迭代器对象?

迭代器: iterato

从语法层面上讲,内置有__iter__()__next__()方法的的对象, 内置可以iter()next()的对象

如何得到迭代器对象?

可迭代对象执行__iter__()iter()得到了迭代器对象

迭代器对象执行__iter__()iter()仍然是迭代器本身

探讨部分:

迭代器执行__iter__()方法和iter()就是迭代器本身, 为什么迭代器对象下也要有内置__iter__()方法和iter()?

主要为了满足for循环迭代取值. for循环上来的第一件事就是调用你需要遍历的对象下的__iter__()方法, 无论你需要遍历的对象是可迭代对象, 还是迭代器对象. 减少这种区分的可能性.

示例:

# 示例一: 调用可迭代对象下的__iter__()方法或者iter()会将其转换成迭代器对象
dic = {'a': 1, 'b': 2, 'c': 3}
dic_iterator = dic.__iter__()

# 示例二: 转换成迭代器对象以后, 就可以使用内置方法__next__()或者next()迭代取值, 且每迭代取值一次, 都会作为下一次迭代取值的初始值.(字典默认迭代的是key)
print(dic_iterator.__next__())  # a
print(dic_iterator.__next__())  # b
print(dic_iterator.__next__())  # c

# 示例三: 当迭代器对象迭代完毕以后, 继续迭代会抛出异常: StopIteration
print(dic_iterator.__next__())  # 抛出异常: StopIteration

# 示例四: 当抛出异常时, 也就是迭代器对象被迭代取值完毕时, 我们可以使用异常处理机制捕捉异常
'''
# 伪代码示例: 
try: 
	会出现异常的代码
except 捕捉的抛出异常的类型:
	捕捉异常以后要继续进行的操作
'''
dic_iterator = dic.__iter__()
while True:
    try:
        print(dic_iterator.__next__())
    except StopIteration:
        break

# 示例五: 基于示例四, 在迭一个迭代器迭代取值干净的情况下, 再对其取值取不到. 如果需要再次取值, 需要对可迭代对象重新使用__iter__()或者iter()生成一个新的迭代器对象.
print('=======>')  # =======>
dic_iterator = dic.__iter__()
while True:
    try:
        print(dic_iterator.__next__())
    except StopIteration:
        break

总结:

1. 调用可迭代对象下的`__iter__()`方法或者`iter()`会将其转换成迭代器对象 
2.  转换成迭代器对象以后, 就可以使用内置方法`__next__()`或者`next()`迭代取值, 且每迭代取值一次, 都会作为下一次迭代取值的初始值.(字典默认迭代的是key)
3.  当迭代器对象迭代完毕以后, 继续迭代会抛出异常: `StopIteration `
4. 当抛出异常时, 也就是迭代器对象被迭代取值完毕时, 我们可以使用异常处理机制捕捉异常 
5. 在迭一个迭代器迭代取值干净的情况下, 再对其取值取不到. 如果需要再次取值, 需要对可迭代对象重新使用`__iter__()`或者`iter()`生成一个新的迭代器对象

四、for循环原理

for循环与while循环

while循环称之为条件循环, 条件为False, 循环结束.
for循环也可以称之为迭代循环, 遍历对象迭代取值完毕, 循环结束.

for 循环低层原理:

迭代取值做的三件事:

  1. 把准备要遍历的对象, 无论是什么类型, 上来直接使用内置的__iter__()方法得到一个迭代器对象.
  2. 然后通过拿到的迭代器对象, 直接使用内置的__next__()迭代取值, 把取到的值赋值给in前面自定义的变量名.
  3. 循环往复步骤2, 直到迭代取值完毕抛出异常StopIteration, 接着for循环会捕捉异常, 最后结束循环.

示例:

# 示例: 使用for循环遍历取值
goods = ['mac', 'lenovo', 'acer', 'dell', 'sony']
for item in goods:
    print(item, end=' ')  # mac lenovo acer dell sony 
    
# 示例: 调用list()功能, 与for循环原理相同    
list('hello')

# 使用while循环 + try...except实现迭代取值. 迭代器迭代完毕except捕获异常: StopIteration
goods = ['mac', 'lenovo', 'acer', 'dell', 'sony']
iterator_goods = iter(goods)
while True:
    try:
        print(next(iterator_goods), end=' ')  # mac lenovo acer dell sony
    except StopIteration:
        break

五、总结

可迭代对象与迭代器对象之间的关系

可迭代对象:

  1. 从语法层面上讲, 内置有__iter__()方法和可以使用iter()的对象
  2. 可迭代对象可以通过__iter__()方法或者可以使用iter()得到迭代器对象
示例:
可迭代对象.__iter__() --> 生成迭代器对象
iter(可迭代对象) ---> 生成迭代器对象

迭代器对象:

  1. 从语法层面上讲, 内置有__next__()方法和可以使用next(), 也能使用__it

  2. 迭代器对象执行__next__()方法或者使用next()得到迭代器的下一个值

    • 示例

      迭代器对象.__next__() --> 迭代器的下一个值
      next(迭代器对象) --> 迭代器的下一个值
      
  3. 迭代器对象执行__iter__()方法或者使用iter()得到迭代器本身.(调用了和没调用一模一样)

    • 示例:

      迭代器对象.__iter__() --> 得到迭代器本身
      iter(迭代器对象) --> 得到迭代器本身
      
    • 验证:

      #迭代器对象执行__iter__()方法或者使用iter()得到迭代器本身.(调用了和没调用一模一样)
      dic = {'a': 1, 'b': 2, 'c': 3}
      dic_iterator = iter(dic)
      
      print(dic_iterator is iter(dic_iterator).__iter__().__iter__())  # True
      

迭代器的优缺点

优点:

  1. 提供了一种不依赖与索引一种通用迭代取值方案
  2. 惰性计算: 对迭代器本身来说, 同一时刻在内存中只有一个值, 它可以存放无限大的数据流.,可以节省内存

缺点:

  1. 取值麻烦,无法预测值的长度
  2. 不能控制取值顺序, 只能取下一个值, 更不能回到开始,调用时一次性的,若想重新获取值, 只能重新调用__iter__()方法和iter()生成一个新的迭代器.

相关文章:

  • python之三元表达式、生成式、生成器表达式
  • 面向过程编程思想与匿名函数及其应用
  • python之函数递归与调用
  • python之二分法
  • python之json模块
  • python之pickle模块
  • python之time与datetime模块
  • python之random模块
  • python之os模块
  • shutil模块
  • shelve 模块
  • typing模块
  • 压缩zipfile与解压缩tarfile模块
  • pyecharts 模块的简单使用
  • hashlib 与 hmac 模块
  • “Material Design”设计规范在 ComponentOne For WinForm 的全新尝试!
  • 5分钟即可掌握的前端高效利器:JavaScript 策略模式
  • AWS实战 - 利用IAM对S3做访问控制
  • centos安装java运行环境jdk+tomcat
  • HTTP中的ETag在移动客户端的应用
  • JavaScript 事件——“事件类型”中“HTML5事件”的注意要点
  • JavaScript标准库系列——Math对象和Date对象(二)
  • java小心机(3)| 浅析finalize()
  • Python 基础起步 (十) 什么叫函数?
  • Python学习之路13-记分
  • rc-form之最单纯情况
  • 闭包--闭包作用之保存(一)
  • 分享自己折腾多时的一套 vue 组件 --we-vue
  • 前端性能优化——回流与重绘
  • 如何实现 font-size 的响应式
  • 如何用vue打造一个移动端音乐播放器
  • 使用 QuickBI 搭建酷炫可视化分析
  • 通信类
  • 用Node EJS写一个爬虫脚本每天定时给心爱的她发一封暖心邮件
  • k8s使用glusterfs实现动态持久化存储
  • 测评:对于写作的人来说,Markdown是你最好的朋友 ...
  • 湖北分布式智能数据采集方法有哪些?
  • ​软考-高级-系统架构设计师教程(清华第2版)【第12章 信息系统架构设计理论与实践(P420~465)-思维导图】​
  • ​一些不规范的GTID使用场景
  • # 计算机视觉入门
  • #控制台大学课堂点名问题_课堂随机点名
  • #我与Java虚拟机的故事#连载09:面试大厂逃不过的JVM
  • ${factoryList }后面有空格不影响
  • (C++17) std算法之执行策略 execution
  • (delphi11最新学习资料) Object Pascal 学习笔记---第8章第5节(封闭类和Final方法)
  • (NSDate) 时间 (time )比较
  • (二)正点原子I.MX6ULL u-boot移植
  • (二十五)admin-boot项目之集成消息队列Rabbitmq
  • (生成器)yield与(迭代器)generator
  • (十)T检验-第一部分
  • (转)IIS6 ASP 0251超过响应缓冲区限制错误的解决方法
  • (转)重识new
  • .gitignore
  • .net php 通信,flash与asp/php/asp.net通信的方法
  • .NET 命令行参数包含应用程序路径吗?