itertools
模块详解itertools
是 Python 标准库中用于高效处理迭代任务的模块,提供了一系列生成迭代器的工具函数,适用于组合生成、数据分组、无限序列等场景,能显著简化代码并优化性能。
itertools
的函数可分为三类:
函数 | 描述 | 示例 |
---|---|---|
**count(start, step) ** |
生成从 start 开始,步长为 step 的无限序列。 |
itertools.count(10, 5) → 10, 15, 20, ... |
**cycle(iterable) ** |
无限循环重复给定可迭代对象。 | itertools.cycle('AB') → A, B, A, B, ... |
**repeat(value, times) ** |
重复生成 value ,默认无限次,或指定 times 次。 |
itertools.repeat(3, 2) → 3, 3 |
2. 有限迭代器
函数 | 描述 | 示例 |
---|---|---|
**chain(*iterables) ** |
将多个可迭代对象连接为单个迭代器。 | chain('AB', [1,2]) → A, B, 1, 2 |
**groupby(iterable, key) ** |
根据 key 函数对相邻元素分组(需先排序)。 |
groupby([1,1,2,3], key=lambda x: x%2) → (0, [1,1]), (1, [2,3]) |
**islice(iterable, start, stop, step) ** |
对迭代器进行切片(类似列表切片,但支持无限迭代器)。 | islice(count(0), 2, 10, 2) → 2,4,6,8 |
**takewhile(pred, iterable) ** |
取元素直到 pred 返回 False 。 |
takewhile(lambda x: x<5, [1,3,5,2]) → 1, 3 |
**dropwhile(pred, iterable) ** |
跳过元素直到 pred 返回 False ,之后保留所有元素。 |
dropwhile(lambda x: x<3, [1,2,0,4]) → 0,4 |
**zip_longest(*iterables, fillvalue) ** |
类似 zip ,但按最长输入填充缺失值。 |
zip_longest('AB', [1], fillvalue='-') → ('A',1), ('B','-') |
**accumulate(iterable, func) ** |
生成累积结果(默认累加,可自定义函数)。 | accumulate([1,2,3], lambda a,b: a*b) → 1, 2, 6 |
**tee(iterable, n) ** |
复制一个迭代器为 n 个独立迭代器。 |
a, b = tee([1,2]) → a 和 b 均可迭代 1,2 |
3. 组合迭代器
函数 | 描述 | 示例 |
---|---|---|
**product(*iterables, repeat) ** |
生成多个可迭代对象的笛卡尔积(全排列)。 | product('AB', [1,2]) → ('A',1), ('A',2), ('B',1), ('B',2) |
**permutations(iterable, r) ** |
生成长度为 r 的所有排列(顺序敏感)。 |
permutations('AB', 2) → ('A','B'), ('B','A') |
**combinations(iterable, r) ** |
生成长度为 r 的所有组合(顺序不敏感)。 |
combinations('ABC', 2) → ('A','B'), ('A','C'), ('B','C') |
**combinations_with_replacement(iterable, r) ** |
允许元素重复的组合。 | combinations_wr('AB', 2) → ('A','A'), ('A','B'), ('B','B') |
chain
)合并多个数据源:
python
import itertools
files = ["data1.csv", "data2.csv"]
databases = [fetch_db1(), fetch_db2()]
all_data = itertools.chain(files, databases)
for item in all_data:
process(item)
groupby
)按条件分组数据(需先排序):
python
from itertools import groupby
data = sorted([("a", 1), ("b", 2), ("a", 3)], key=lambda x: x[0])
for key, group in groupby(data, key=lambda x: x[0]):
print(f"Key: {key}, Items: {list(group)}")
# Output:
# Key: a, Items: [('a', 1), ('a', 3)]
# Key: b, Items: [('b', 2)]
product
)生成坐标网格:
python
from itertools import product
for x, y in product(range(3), repeat=2):
print(f"({x}, {y})")
# Output: (0,0), (0,1), ..., (2,2)
islice
)分页读取大型文件:
python
from itertools import islice
def read_in_chunks(file, chunk_size=1000):
while True:
chunk = list(islice(file, chunk_size))
if not chunk:
break
yield chunk
with open("large_file.txt") as f:
for page in read_in_chunks(f):
process(page)
count
+ map
)生成斐波那契数列:
python
from itertools import count, islice
def fibonacci():
a, b = 0, 1
while True:
yield a
a, b = b, a + b
# 获取前10个斐波那契数
print(list(islice(fibonacci(), 10))) # [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
combinations
+ filter
)筛选符合条件的组合:
python
from itertools import combinations
numbers = [1, 2, 3, 4]
# 找出所有和为5的两数组合
valid_pairs = [pair for pair in combinations(numbers, 2) if sum(pair) == 5]
print(valid_pairs) # [(1,4), (2,3)]
accumulate
)计算移动平均值:
python
from itertools import accumulate
data = [10, 20, 30, 40]
cumulative = list(accumulate(data)) # [10, 30, 60, 100]
window_size = 2
moving_avg = [ (cum[i] - (cum[i-window_size] if i>=window_size else 0))/window_size
for i, cum in enumerate(cumulative, 1)]
print(moving_avg) # [10.0, 15.0, 25.0, 35.0]
takewhile
或 islice
。groupby
需先排序**:仅对连续相同键的元素分组,未排序时可能无法正确分组。chain
、groupby
、product
、permutations
、islice
。