Skip to content

itertools - 增强可迭代对象的模块

itertools 是 Python 的一个标准库模块,提供了用于操作和生成迭代器的多种工具。它包含了用于高效循环和处理迭代器的函数,能够让你在处理大量数据时减少内存消耗,同时提供了更简洁的代码。

itertools 的主要功能包括:

  1. 创建无限迭代器:例如,生成一个可以永远输出相同值或按一定规律变化的迭代器。
  2. 生成有限的迭代器:例如,生成指定长度的排列组合或按条件过滤元素。
  3. 操作已有的迭代器:例如,链接多个迭代器、重复迭代器的元素、限制迭代器的输出等。

它提供了

无穷迭代器:

迭代器实参结果示例
count()[start[, step]]start, start+step, start+2*step, ...count(10) → 10 11 12 13 14 ...
cycle()pp0, p1, ... plast, p0, p1, ...cycle('ABCD') → A B C D A B C D ...
repeat()elem [,n]elem, elem, elem, ... 重复无限次或n次repeat(10, 3) → 10 10 10

根据最短输入序列长度停止的迭代器:

迭代器实参结果示例
accumulate()p [,func]p0, p0+p1, p0+p1+p2, ...accumulate([1,2,3,4,5]) → 1 3 6 10 15
batched()p, n(p0, p1, ..., p_n-1), ...batched('ABCDEFG', n=3) → ABC DEF G
chain()p, q, ...p0, p1, ... plast, q0, q1, ...chain('ABC', 'DEF') → A B C D E F
chain.from_iterable()iterable -- 可迭代对象p0, p1, ... plast, q0, q1, ...chain.from_iterable(['ABC', 'DEF']) → A B C D E F
compress()data, selectors(d[0] if s[0]), (d[1] if s[1]), ...compress('ABCDEF', [1,0,1,0,1,1]) → A C E F
dropwhile()predicate, seqseq[n], seq[n+1], 从 predicate 未通过时开始dropwhile(lambda x: x<5, [1,4,6,3,8]) → 6 3 8
filterfalse()predicate, seqpredicate(elem) 未通过的 seq 元素filterfalse(lambda x: x<5, [1,4,6,3,8]) → 6 8
groupby()iterable[, key]根据key(v)值分组的迭代器
islice()seq, [start,] stop [, step]seq[start:stop:step]中的元素islice('ABCDEFG', 2, None) → C D E F G
pairwise()iterable -- 可迭代对象(p[0], p[1]), (p[1], p[2])pairwise('ABCDEFG') → AB BC CD DE EF FG
starmap()func, seqfunc(*seq[0]), func(*seq[1]), ...starmap(pow, [(2,5), (3,2), (10,3)]) → 32 9 1000
takewhile()predicate, seqseq[0], seq[1], 直到 predicate 未通过takewhile(lambda x: x<5, [1,4,6,3,8]) → 1 4
tee()it, nit1, it2, ... itn 将一个迭代器拆分为n个迭代器
zip_longest()p, q, ...(p[0], q[0]), (p[1], q[1]), ...zip_longest('ABCD', 'xy', fillvalue='-') → Ax By C- D-

排列组合迭代器:

迭代器实参结果
product()p, q, ... [repeat=1]笛卡尔积,相当于嵌套的for循环
permutations()p[, r]长度r元组,所有可能的排列,无重复元素
combinations()p, r长度r元组,有序,无重复元素
combinations_with_replacement()p, r长度r元组,有序,元素可重复
例子结果
product('ABCD', repeat=2)AA AB AC AD BA BB BC BD CA CB CC CD DA DB DC DD
permutations('ABCD', 2)AB AC AD BA BC BD CA CB CD DA DB DC
combinations('ABCD', 2)AB AC AD BC BD CD
combinations_with_replacement('ABCD', 2)AA AB AC AD BB BC BD CC CD DD

示例

下列模块函数均创建并返回迭代器。有些迭代器不限制输出流长度,所以它们只应在能截断输出流的函数或循环中使用。

python
itertools.accumulate(iterable[, function, *, initial=None])

对一个可迭代对象的元素进行累积操作,生成一个累积结果的迭代器。这个函数的作用是将每个元素与前面的累积值结合,通过给定的函数(如果提供)生成新的累积值,直到处理完所有的元素。

function 默认为加法运算。 function 应当接受两个参数,即一个累积汇总值和一个来自 iterable 的值。

如果提供了 initial 值,将从该值开始累积并且输出将比输入可迭代对象多一个元素。

python
data = [3, 4, 6, 2, 1, 9, 0, 7, 5, 8]
>>> list(accumulate(data, max))              # 运行最大值
[3, 4, 6, 6, 6, 9, 9, 9, 9, 9]
>>> list(accumulate(data, operator.mul))     # 运行乘积
[3, 12, 72, 144, 144, 1296, 0, 0, 0, 0]

# 分期偿还利率 5% 总额 1000 的货款,每年还款 10 次,每次 90
>>> update = lambda balance, payment: round(balance * 1.05) - payment
>>> list(accumulate(repeat(90, 10), update, initial=1_000))
[1000, 960, 918, 874, 828, 779, 728, 674, 618, 559, 497]

python
itertools.chain(*iterables)

创建一个迭代器,它首先返回第一个可迭代对象中所有元素,接着返回下一个可迭代对象中所有元素,直到耗尽所有可迭代对象中的元素。可将多个序列处理为单个序列。

python
>>> list(chain([1, 2, 3], [4, 5, 6]))
[1, 2, 3, 4, 5, 6]

python
itertools.product(*iterables, repeat=1)

可迭代对象输入的笛卡儿积。

大致相当于生成器表达式中的嵌套循环。例如, product(A, B)((x,y) for x in A for y in B) 返回结果一样。

原生写法:

python
list1 = [1, 2, 3]
list2 = [4, 5, 6]
list3 = [7, 8, 9]

for i in list1:
    for j in list2:
        for k in list3:
            print(i, j, k)

使用 itertools.product

python
from itertools import product

for i, j, k in product(list1, list2, list3):
    print(i, j, k)

python
itertools.permutations(iterable, r=None)

根据 iterable 返回连续的 r 长度元素的排列。

如果 r 未指定或为 Noner 默认设置为 iterable 的长度,这种情况下,生成所有全长排列。

python
import itertools

numbers = [1, 2, 3]

for i in itertools.permutations(numbers):
    print(i)
运行结果
(1, 2, 3)
(1, 3, 2)
(2, 1, 3)
(2, 3, 1)
(3, 1, 2)
(3, 2, 1)

如果长度为2:

python
import itertools

numbers = [1, 2, 3]

for i in itertools.permutations(numbers, 2):
    print(i)
运行结果
(1, 2)
(1, 3)
(2, 1)
(2, 3)
(3, 1)
(3, 2)

python
itertools.combinations(iterable, r)

返回由输入 iterable 中元素组成长度为 r 的子序列。

就上下文而言,组合是一种排列顺序无关紧要的排列。如 (1, 2, 3)(1, 3, 2) 这两个组合被认为是完全相同的,因为组合在顺序中不重要。

python
import itertools

numbers = [1, 2, 3, 4]

for i in itertools.combinations(numbers, 3):
    print(i)

python
itertools.combinations_with_replacement(iterable, r)

返回由输入 iterable 中元素组成的长度为 r 的子序列,允许每个元素可重复出现。

它和 combinations 不同的就是它允许每个元素多次出现。

python
import itertools

numbers = [1, 2, 3]

for i in itertools.combinations_with_replacement(numbers, 2):
    print(i)
运行结果
(1, 1)
(1, 2)
(1, 3)
(2, 2)
(2, 3)
(3, 3)

python
itertools.cycle(iterable)

无限生成由 iterable 指定的元素序列。

python
import itertools
import time

numbers = [1, 2, 3]

for i in itertools.cycle(numbers):
    print(i, end=' ')
    time.sleep(0.1)
    
    # 1 2 3 1 2 3 1 2 3 ...

python
itertools.count(start=0, step=1)

创建一个迭代器,它返回从 start 开始的均匀间隔的值。 可与 map()]配合使用以生成连续的数据点或与 zip() 配合使用以添加序列数字。

当对浮点数计数时,替换为乘法代码有时会有更高的精度,例如: (start + step * i for i in count())

python
import itertools

for n in itertools.count(start=1, step=2):
    print(n)
运行结果
1
3
5
7
9
11
13
15
...

为方便开发而创建的常用库指南