Python 进阶之路(一)Python 从基础到进阶—— 控制流(2)深入理解 for 语句和 with 语句

  • 1、可迭代对象和 for 语句
  • 2、上下文管理器和 with 语句

1. 总结

1.1 概念区分

可得迭代对象、迭代器和生成器?

一句话:迭代器和生成器都属于可迭代对象,含有__iter__和__next__魔法函数的对象都是迭代器(可以为你的类添加迭代器),生成器是一种快速创建迭代器的方法。

在这里插入图片描述

迭代器(Iterator)

  • 可以被next()函数调用并不断返回下一个值的对象称为迭代器(Iterator)。迭代器(iterator)是惰性可迭代对象(lazy iterable),是一次性可迭代对象。

    可以使用isinstance()判断一个对象是否是Iterator对象。

生成器:特殊迭代器

  • 生成器(来自于生成器函数或者生成器表达式)其实是一种特殊的迭代器

可迭代对象( Iterable)

  • 可以直接作用于for循环的对象统称为可迭代对象(Iterable)。包括两类数据类型:

    一类是容器数据类型,如list、tuple、dict、set、str等;
    一类是生成器,包括生成器表达式和带yield的生成器函数。

    可以使用isinstance()判断一个对象是否是Iterable对象。

    注意:list、dict、str虽然是Iterable,却不是Iterator。(因为Python的Iterator对象表示的是一个数据流)
    把list、dict、str等Iterable变成Iterator可以使用iter()函数。

1.2 本质

在这里插入图片描述

  • 迭代器是包含__next__方法的对象。(__next__方法可以记住遍历的位置)
  • 可迭代的对象是可直接用于遍历的对象,包含__iter__方法。Iterable的__iter__方法会返回一个Iterator(iter()函数会返回一个定义了next()方法的迭代器对象)

2. 迭代器:惰性可迭代对象

在这里插入图片描述
记住:迭代器的存在是为了管理 for 语句

迭代(Iteration)是访问集合元素(collection)的一种方式。迭代器(Iterator )是一个可以记住遍历的位置的对象。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。

注意:
1.在迭代器对象上调用 iter() 函数时,总会返回相同的对象
2.迭代器对象一定可以使用 next() 函数
3.迭代器对象只能被遍历一次

特殊的惰性迭代对象:range()

偶然发现一个有意思的事情:type(range)的结果是typetype(range(3))的结果是range,不禁思考 type 同 object 的关系,以及***range 代表的是什么类型***。
具体可以参考 Python 核心知识 0 ——框架&总章 中的Python基础知识。

range()函数是一个可得迭代对象(其本身不是迭代器),它本身可以返回一个迭代器(可以调用next函数),而不是一个列表类型。

  • 语法

range(stop)
range(start, stop[, step])

返回的是一个可迭代对象:步数为step、从start 到 stop-1 的整数序列。

  • 用法

① 与 for 循环一起使用;
② 使用 list() 函数转换为列表(可以打印出来)

  • 例子
range(3) # 返回的是一个迭代器

range(0, 3)
for i in range(3):
    print(i)

0
1
2
list(range(3))

[0, 1, 2]

返回迭代器的内置函数

在这里插入图片描述注意上面图片上的错误:range()比较特殊,并不是返回一个迭代器,而只是返回一个可迭代对象。

下面就是一些能够返回迭代器的 Python 内置函数:

enumerate()

  • 语法
    enumerate(sequence, [start=0])

输入一个序列,返回 enumerate(枚举) 对象。

  • 用法
    ① 与 for 循环一起使用;
    ② 使用 list() 函数转换为列表(可以打印出来)

  • 例子

enumerate(range(4, 7))

<enumerate at 0x1126a9948>
for n, i in enumerate(range(4, 7)) :
    print(n, i)

0 4
1 5
2 6

list(enumerate(range(3)))

[(0, 0), (1, 1), (2, 2)]

reversed()

  • 语法
    reversed(seq)
    返回一个反转的迭代器。

  • 例子

reversed(range(3))

<range_iterator at 0x1131485a0>
for i in reversed(range(3)):
    print(i)

2
1
0

list(reversed(range(3)))

[2, 1, 0]

zip()

  • 语法
    zip(iter1 [,iter2 […]])

返回一个 zip 对象,其.next()方法会返回一个元组。

  • 例子
zip(range(3), range(3,6))

<zip at 0x112a974c8>
list(zip(range(3), range(3,6)))

[(0, 3), (1, 4), (2, 5)]

sorted()

  • 语法
    sorted(iterable, key=None, reverse=False)

返回可迭代对象重新排序的列表

  • 例子
sorted((3,7,1,0,5))  


[0, 1, 3, 5, 7]

注意:区分list的方法 list.sort()

附:
Python 内置函数数量没有想的那么多,可以顺带多学习学习:Python3 内置函数

3. 生成器

在这里插入图片描述
定义生成器的两种方法:生成器表达式和生成器函数

  • 生成器表达式。生成器表达式是列表推倒式的生成器版本,看起来像列表推导式,但是它返回的是一个生成器对象而不是列表对象。只要把一个列表生成式的[]改成(),就创建了一个generator。
  • 如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator。

4. 上下文管理器和 with 语句

4.1 概述

含有 __enter____exit__ 方法的对象就是 Python 的上下文管理器(Context Managers)。

上下文管理器存在的目的是管理 with 语句,就像是迭代器的存在是为了管理 for 语句一样。

with 上下文管理器:
        语句体

当 with 遇到上下文管理器,就会在执行语句体之前,先执行上下文管理器的 enter 方法,然后再执行语句体,执行完语句体后,最后执行 exit 方法。
with 有一个很重要的作用简化 try/finally 模式,无论何种异常发生,finally 字句都会执行。

4.2 实例

  • 有问题的代码
file = open("1.txt")
data = file.read()
file.close()

问题:可能出现 ①文件读取发生异常但没有进行任何处理 ② 肯能忘记关闭文件句柄

  • 改进代码
try:
    f = open('xxx')
except:
    print('fail to open')
    exit(-1)
try:
    do something
except:
    do something
finally:
    f.close()

虽然这段代码运行良好,但比较冗长。

  • with 语句
    使用with的话,能够减少冗长,还能自动处理上下文环境产生的异常
with open('1.txt') as file:
    data = file.read()

参考:

文件的打开、读写和关闭:

  • 文件打开后才能进行读写
  • Python会缓存写入的数据,如果程序异常崩溃,数据就不能写入到文件当中。安全起见,文件用完后要主动关闭文件
  1. 完全理解Python迭代对象、迭代器、生成器
  2. 如何更好地理解Python迭代器和生成器?
  3. Python中生成器和迭代器的区别
  4. python之美
  5. Python 中 with用法及原理
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值