itertools模块

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 可以减少编写代码的复杂度,并且在需要频繁迭代的场合可以提高程序的效率。在实际编程过程中,需要根据实际需求选择使用适当的函数或类。

后端开发标签