粗谈Python内置库itertools
admin
2023-07-30 20:43:48
0

官方对itertools的定义是Functions creating iterators for efficient looping,定义了一系列的方法,能帮助我们创建能够进行高效遍历迭代的迭代器,里面包含不少有意思并且有用的方法,比如像chain, izip/izip_longest, combinations, ifilter等等。

在这里简单拿几个方法为例,简单分析一下文档里面给出的等效的实现的方式还有平时我们能够使用的场景。

chain

如同chain的名称还有签名itertools.chain(*iterables)所示,我们能用它将一系列的可迭代对象串联起来,这样就能连续的对多个迭代对象的内容进行迭代:

>>> itertools.chain(\'ABC\', \'DEF\')

>>> for item in itertools.chain(\'ABC\', \'DEF\'):
...     print item,
... 
A B C D E F

从上面的打印日志里面能够看到,调用itertools.chain生成了一个迭代器对象,在python的itertools内置库里面,chain被实现成一个继承自object的一个对象,实现了next, __iter__方法(将自己实现成一个可迭代对象,迭代器),调用时其实是调用它的__init__(self, *iterables)方法初始化了一个对象,然后接下来进行迭代。简化的等效的实现方式类似:

def chain(*iterables):
    for it in iterables:
        for element in it:
            yield element

传递给chain的多个可迭代对象呗保存在元组类型的变量iterables里面,遍历每一个可迭代对象里面的每一个对象,上面等效实现的方式里面是用yield的实现的,当对串联的结果比如说用for进行遍历的时候,yield能够每次返回一条数据,中断,外面我们自己的代码执行(或输出或其它的操作)如此循环反复知道遍历结束(StopIteration error throwed)。

combinations

这个方法能够帮助我们生成一个列表中,按照顺序能够有的所有组合,当然生成依然是迭代器对象。

>>> itertools.combinations(\'ABCDA\', 2)

>>> for item in itertools.combinations(\'ABCDA\', 2):
...     print item
... 
(\'A\', \'B\')
(\'A\', \'C\')
(\'A\', \'D\')
(\'A\', \'A\')
(\'B\', \'C\')
(\'B\', \'D\')
(\'B\', \'A\')
(\'C\', \'D\')
(\'C\', \'A\')
(\'D\', \'A\')

chain的实现方式差不多是一样的,实现了next, __iter__方法(将自己实现成一个可迭代对象,迭代器),调用时其实是调用它的__init__(self, iterable, r)方法初始化了一个combinations对象,然后能够对它进行迭代。等效的实现方式差不多像这样:

def combinations(iterable, r):
    # combinations(\'ABCD\', 2) --> AB AC AD BC BD CD
    # combinations(range(4), 3) --> 012 013 023 123
    pool = tuple(iterable)
    n = len(pool)
    if r > n:
        return
    indices = range(r)
    yield tuple(pool[i] for i in indices)
    while True:
        for i in reversed(range(r)):
            if indices[i] != i + n - r:
                break
        else:
            return
        indices[i] += 1
        for j in range(i+1, r):
            indices[j] = indices[j-1] + 1
        yield tuple(pool[i] for i in indices)

其实这个等效的实现的方式也很有意思,里面充分你的利用了yield的特性,中断返回值后能够将现场的环境保持下来,比如例子中,变量indices的值在每次返回值之后都能继续保存,这样里面记录的索引值才能正确递进,直到迭代结束。

itertools这个内置库里面的提供的一些服用方法能够很大简化平时需要做的一些工作,而且高效。也能方便结合operator里面的一些计算的方法一起使用,代码能精简很多。官方的文档里面详细的介绍了各个方法的实现和使用,希望这篇流水账能够起个引言的作用。

参考资料:itertools — Functions creating iterators for efficient looping

相关内容

热门资讯

Mobi、epub格式电子书如... 在wps里全局设置里有一个文件关联,打开,勾选电子书文件选项就可以了。
定时清理删除C:\Progra... C:\Program Files (x86)下面很多scoped_dir开头的文件夹 写个批处理 定...
500 行 Python 代码... 语法分析器描述了一个句子的语法结构,用来帮助其他的应用进行推理。自然语言引入了很多意外的歧义,以我们...
scoped_dir32_70... 一台虚拟机C盘总是莫名奇妙的空间用完,导致很多软件没法再运行。经过仔细检查发现是C:\Program...
65536是2的几次方 计算2... 65536是2的16次方:65536=2⁶ 65536是256的2次方:65536=256 6553...
小程序支付时提示:appid和... [Q]小程序支付时提示:appid和mch_id不匹配 [A]小程序和微信支付没有进行关联,访问“小...
pycparser 是一个用... `pycparser` 是一个用 Python 编写的 C 语言解析器。它可以用来解析 C 代码并构...
微信小程序使用slider实现... 众所周知哈,微信小程序里面的音频播放是没有进度条的,但最近有个项目呢,客户要求音频要有进度条控制,所...
Apache Doris 2.... 亲爱的社区小伙伴们,我们很高兴地向大家宣布,Apache Doris 2.0.0 版本已于...
python清除字符串里非数字... 本文实例讲述了python清除字符串里非数字字符的方法。分享给大家供大家参考。具体如下: impor...