主题
itertools - 增强可迭代对象的模块
itertools
是 Python 的一个标准库模块,提供了用于操作和生成迭代器的多种工具。它包含了用于高效循环和处理迭代器的函数,能够让你在处理大量数据时减少内存消耗,同时提供了更简洁的代码。
itertools
的主要功能包括:
- 创建无限迭代器:例如,生成一个可以永远输出相同值或按一定规律变化的迭代器。
- 生成有限的迭代器:例如,生成指定长度的排列组合或按条件过滤元素。
- 操作已有的迭代器:例如,链接多个迭代器、重复迭代器的元素、限制迭代器的输出等。
它提供了
无穷迭代器:
迭代器 | 实参 | 结果 | 示例 |
---|---|---|---|
count() | [start[, step]] | start, start+step, start+2*step, ... | count(10) → 10 11 12 13 14 ... |
cycle() | p | p0, 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, seq | seq[n], seq[n+1], 从 predicate 未通过时开始 | dropwhile(lambda x: x<5, [1,4,6,3,8]) → 6 3 8 |
filterfalse() | predicate, seq | predicate(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, seq | func(*seq[0]), func(*seq[1]), ... | starmap(pow, [(2,5), (3,2), (10,3)]) → 32 9 1000 |
takewhile() | predicate, seq | seq[0], seq[1], 直到 predicate 未通过 | takewhile(lambda x: x<5, [1,4,6,3,8]) → 1 4 |
tee() | it, n | it1, 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 未指定或为 None
,r 默认设置为 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
...