iter
iter() 函数用来生成迭代器,返回一个 iterator 对象。
iter(object[, sentinel])
根据是否存在第二个实参,第一个实参的解释是非常不同的。
iter(iterable) -> iteratoriter(callable, sentinel) -> iterator
具体为:
- 如果没有第二个实参,
object必须是支持迭代协议(有__iter__()方法)的集合对象,或必须支持序列协议(有__getitem__()方法,且数字参数从 0 开始)。如果它不支持这些协议,会触发TypeError。 - 如果有第二个实参
sentinel,那么object必须是可调用的对象。这种情况下生成的迭代器,每次迭代调用它的__next__()方法时都会不带实参地调用object;如果返回的结果是sentinel则触发StopIteration,否则返回调用结果。
适合 iter() 的第二种形式的应用之一是构建块读取器。 例如,从二进制数据库文件中读取固定宽度的块,直至到达文件的末尾:
from functools import partialwith open('mydata.db', 'rb') as f:for block in iter(partial(f.read, 64), b''):process_block(block)
partial(f.read, 64 等价于无参函数 lambda: f.read(64) ,每次循环读取文件 64 字节,当到达文件末尾 b'' 时,触发 StopIteration ,结束循环( for 语句在序列为空或迭代器引发 StopIteration 异常时,结束循环)。
在看一个 chunk 函数例子:
from itertools import islicedef chunk(it, size):"""分割it为等大小的chunk,每个chunk有size个元素,最后一个chunk 可能不足 size个"""it = iter(it)return iter(lambda: tuple(islice(it, size)), ())
>>> list(chunk(range(14), 3))[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11), (12, 13)]
