1. 简介
itertools 模块是 Python 中的标准库之一,提供了一系列用于处理迭代器的函数和类。使用 itertools 可以更加方便地处理迭代器,减少编写代码的复杂度。以下是 itertools 模块中常用的一些函数或类:
count
cycle
repeat
accumulate
chain
product
permutations
combinations
combinations_with_replacement
2. 常用函数和类介绍
2.1 count
count(start=0, step=1)
函数会返回一个无限迭代器,从 start 开始,每次迭代加上 step。可以用于产生一连串连续的数字。下面是一个使用 count 产生数字序列的例子:
from itertools import count
for i in count(1, 2):
if i > 10:
break
print(i)
上面的代码会输出:1 3 5 7 9,因为 1 加 2,每次输出加 2 的结果。
2.2 cycle
cycle(iterable)
函数会生成给定迭代器的无限循环序列。下面是一个使用 cycle 无限循环输出列表元素的例子:
from itertools import cycle
c = cycle([1, 2, 3])
for i in range(5):
print(next(c))
上面的代码会输出:1 2 3 1 2,因为 [1, 2, 3] 循环输出了两次。
2.3 repeat
repeat(object, times=None)
函数会将 object 重复 times 次,当 times 为 None 时则重复无限次。可以用于生成一个重复的序列。下面是一个使用 repeat 函数重复输出元素的例子:
from itertools import repeat
for i in repeat(1, 5):
print(i)
上面的代码会输出:1 1 1 1 1,因为将数字 1 重复输出了 5 次。
2.4 accumulate
accumulate(iterable, func=operator.add)
函数会生成一个累加序列迭代器,每次输出为迭代器前面所有元素的累加结果。如果提供了 func 函数,则使用 func 函数代替默认的加法操作。下面是一个使用 accumulate 函数计算累加结果的例子:
from itertools import accumulate
data = [1, 2, 3, 4, 5]
for i in accumulate(data):
print(i, end=' ')
上面的代码会输出:1 3 6 10 15,因为序列累加结果依次是 [1, 1+2, 1+2+3, 1+2+3+4, 1+2+3+4+5]
。
2.5 chain
chain(*iterables)
函数会将指定的可迭代对象连成一个新的可迭代对象,输出顺序为指定对象的顺序。下面是一个使用 chain 函数输出多个列表内容的例子:
from itertools import chain
a = [1, 2, 3]
b = ['a', 'b', 'c']
for i in chain(a, b):
print(i, end=' ')
上面的代码会输出:1 2 3 a b c,因为将两个列表连成了一个新的列表。
2.6 product
product(*iterables, repeat=1)
函数会将多个序列返回笛卡尔积,也就是将每个序列中的元素依次组合起来,输出的元素个数为各序列长度乘积。下面是一个使用 product 函数计算多个序列的笛卡尔积的例子:
from itertools import product
a = [1, 2, 3]
b = [4, 5]
c = ['+', '-']
for i in product(a, b, c):
print(i, end=', ')
上面的代码会输出:(1, 4, '+'), (1, 4, '-'), (1, 5, '+'), (1, 5, '-'), (2, 4, '+'), (2, 4, '-'), (2, 5, '+'), (2, 5, '-'), (3, 4, '+'), (3, 4, '-'), (3, 5, '+'), (3, 5, '-'),因为将 3 个序列的组合输出了。
2.7 permutations
permutations(iterable, r=None)
函数会返回序列中所有长度为 r 的排列,如果 r 为 None,则返回所有长度的排列。下面是一个使用 permutations 函数计算列表排列的例子:
from itertools import permutations
a = [1, 2, 3]
for i in permutations(a, 2):
print(i, end=', ')
上面的代码会输出:(1, 2), (1, 3), (2, 1), (2, 3), (3, 1), (3, 2),因为将列表的元素进行了 2 个一组的排列。
2.8 combinations
combinations(iterable, r)
函数会返回序列中所有长度为 r 的组合,不同于生成排列,组合不考虑元素的顺序。下面是一个使用 combinations 函数计算列表组合的例子:
from itertools import combinations
a = [1, 2, 3]
for i in combinations(a, 2):
print(i, end=', ')
上面的代码会输出:(1, 2), (1, 3), (2, 3),因此将列表的元素进行了 2 个一组的组合。
2.9 combinations_with_replacement
combinations_with_replacement(iterable, r)
函数会返回序列中所有长度为 r 的组合,允许元素重复。下面是一个使用 combinations_with_replacement 函数计算列表组合的例子:
from itertools import combinations_with_replacement
a = [1, 2, 3]
for i in combinations_with_replacement(a, 2):
print(i, end=', ')
上面的代码会输出:(1, 1), (1, 2), (1, 3), (2, 2), (2, 3), (3, 3),因为将列表的元素进行了 2 个一组的组合,允许重复。
3. 效率问题
itertools 本质上是一个迭代工具,因此在一些需要频繁迭代的场合,使用 itertools 可以较大程度地提高程序的执行效率。
下面是一个使用 itertools 和普通方式生成斐波那契数列的效率比较:
import time
from itertools import islice
# 普通方式生成斐波那契数列
def fib(n):
a, b = 0, 1
for _ in range(n):
a, b = b, a + b
yield a
start_time = time.time()
list(fib(1000000))
end_time = time.time()
print('普通方式生成斐波那契数列用时:', end_time-start_time)
# 使用 itertools 生成斐波那契数列
def ifib():
a, b = 0, 1
while True:
yield a
a, b = b, a + b
start_time = time.time()
list(islice(ifib(), 1000000))
end_time = time.time()
print('使用 itertools 生成斐波那契数列用时:', end_time-start_time)
上面的代码会输出:
普通方式生成斐波那契数列用时: 0.2739236354827881
使用 itertools 生成斐波那契数列用时: 0.14595389366149902
使用 itertools 生成斐波那契数列的时间是普通方式的一半左右,因此在需要对迭代器进行大量操作时,使用 itertools 可以提高程序的效率。
4. 总结
itertools 模块提供了一些方便快捷的函数和类用于处理迭代器。使用 itertools 可以减少编写代码的复杂度,并且在需要频繁迭代的场合可以提高程序的效率。在实际编程过程中,需要根据实际需求选择使用适当的函数或类。