Python随笔——你不知道的iter()(接受两个参数)

iter()

提到iter(),可能你想到的就是传入一个iteratable对象作为参数,然后将其转换为一个iterator对象。但不得不提,iter()其实还可以接受两个参数。
iter(object[, sentinel])

  • 当只有一个参数时:object 必须是支持迭代协议(有__iter__() 方法)的集合对象;或必须支持序列协议(有 __getitem__() 方法,且数字参数从 0 开始)。
  • 当有两个参数时,那么object 必须是可调用的对象,可以简单理解为传入一个函数。 这种情况下生成的迭代器,每次迭代调用它的 __next__() 方法时都会不带实参地调用 object;如果返回的结果是 sentinel 则触发 StopIteration,否则返回调用结果。
import random
from collections import Iterator

def get_number():
    """随机生成1-10的整数"""

    num=random.randint(1,5)
    print(f"The random number is {num}")
    return num


random_number=iter(get_number,5)

#检测是否为Iterator
print(isinstance(random_number,Iterator))

for i in random_number:
    print(f"get number: {i}")

可以看到,iter(object[, sentinel])返回一个iterator对象。每次迭代时,都会调用get_number()函数,生成一个随机数。当迭代过程中生成5时, 与sentinel相匹配,触发 StopIteration,停止迭代。
在这里插入图片描述

应用

构建块读取器

例如,从二进制数据库文件中读取固定宽度的块,直至到达文件的末尾:

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

文本解析

列如,解析字符串中的文本构成。

import re
from collections import namedtuple

NAME = r'(?P<NAME>[a-zA-Z_][a-zA-Z_0-9]*)'
NUM = r'(?P<NUM>\d+)'
PLUS = r'(?P<PLUS>\+)'
TIMES = r'(?P<TIMES>\*)'
EQ = r'(?P<EQ>=)'
WS = r'(?P<WS>\s+)'

master_pat = re.compile('|'.join([NAME, NUM, PLUS, TIMES, EQ, WS]))

def generate_tokens(pat, text):
    Token= namedtuple('Token',['type','value'])
    scanner= pat.scanner(text)

    for m in iter(scanner.match, None):
        yield Token(m.lastgroup, m.group())

for tok in generate_tokens(master_pat, 'foo = 23 + 42 * 10'):
    print(tok)

在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值