Python学习:好像很少人知道 Python iter() 的另外一个用法?

本文介绍了Python中iter()方法的两种使用方式:一种是常见的用于迭代可迭代对象的方法;另一种较少为人知的方式,通过传递一个可调用对象和一个哨兵值来创建迭代器,直至返回值等于哨兵值时停止。

在前面的一期Python学习教程有跟大家介绍过关于序列、可迭代对象、迭代器、生成器的概念,其中有提到过,如果实现了 iter() 和 next() 就是生成器,同时验证可迭代对象最好的方法是 iter(obj) 。

今天我们来介绍下 iter() 方法另外的用法。

据说是很少有人知道这个用法
在这里插入图片描述

一、上代码、学用法

我们都比较熟悉 iter(obj),会返现一个迭代器,如果 obj 不是可迭代对象,则会报错。但其实如果仔细看官方文档,会发现 iter() 方法其实是接受两个参数的,文档说明如下

iter(object[, sentinel])

sentinel 英文翻译为 哨兵。
sentinel 参数是可选的,当它存在时,object 不再传入一个可迭代对象,而是一个可调用对象,通俗点说就是可以通过()调用的对象,而 sentinel 的作用就和它的翻译一样,是一个“哨兵”,当时可调用对象返回值为这个“哨兵”时,循环结束,且不会输出这个“哨兵”。

可能有点难懂,用一个简单需求来说明,需求说明如下:

心里想一个[1, 10]范围的数,然后代码开始随机,当随机到想的数时停止,看每次代码需要随机几次。

实现分析:看起来应该很简单,random,然后加一个if判断即可,但是用 iter() 来实现更简单。实现代码如下:

from random import randint
def guess():
 return randint(0, 10)
num = 1
# 这里先写死心里想的数为5
for i in iter(guess, 5):
 print("第%s次猜测,猜测数字为: %s" % (num, i))
 num += 1
# 当 guess 返回的是 5 时,会抛出异常 StopIteration,但 for 循环会处理异常,即会结束循环
二、还是看看文档吧

关于这两个参数,文档里也说的很详细,分段解释如下:

The first argument is interpreted very differently depending on the
presence of the second argument.

翻译:第一个参数根据第二个参数有不同的含义

Without a second argument, object must be a collection object which
supports the iteration protocol (the iter() method), or it must
support the sequence protocol (the getitem() method with integer
arguments starting at 0). If it does not support either of those
protocols, TypeError is raised.

翻译:如果没有第二个参数,object(即第一个参数)是一个支持迭代器协议(实现_iter_()方法的)的集合对象,或者是支持序列协议(实现_getitem_()方法)且是从0开始索引。如果它不支持其中任何一个,则抛出 TypeError 异常

简单来说就是,如果没有第二个参数,就是我们比较熟悉的用法。代码示例如下:

In [5]: iter("123")
Out[5]: <str_iterator at 0x105c9b9e8>
In [6]: iter([1, 2, 3])
Out[6]: <list_iterator at 0x105f9f8d0>
In [7]: iter(123)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-7-c76acad08c3c> in <module>()
----> 1 iter(123)
TypeError: 'int' object is not iterable

再来看看有第二个参数的情况

If the second argument, sentinel, is given, then object must be a
callable object. The iterator created in this case will call object
with no arguments for each call to its next() method; if the value
returned is equal to sentinel, StopIteration will be raised, otherwise
the value will be returned.

翻译:如果给定了第二个参数 sentinel,object 则必须是一个可调用对象,这个可调用对象没有任何参数,当可调用对象的返回值等于 sentinel 的值时,抛出 StopIteration 的异常,否则返回当前值。(这里如果不好理解可调用对象,可以理解为函数,这样更容易想明白)

对于这个用法的适用场景,文档中也给出了说明:

One useful application of the second form of iter() is to build a
block-reader. For example, reading fixed-width blocks from a binary
database file until the end of file is reached:

翻译:对于第二个参数,一个有用的场景是创建一个 blokc-reader,即根据条件中断读取。比如:从二进制数据库文件读取固定宽度的块,直到到达文件的末尾,代码示例如下:

from functools import partial
with open('mydata.db', 'rb') as f:
 for block in iter(partial(f.read, 64), b''):
 process_block(block)
三、小结一下

1、iter() 方法不管有没有第二个参数,返回的都是迭代器

2、iter() 方法第一个参数的参数类型,根据有无第二个参数决定

其实关于Python学习有很多还有待发掘的用法和方法,欢迎各位小伙伴补充呀!更多的Python学习教程呀会继续为大家更新!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值