Python itertools库介绍 - 统计随机试验(3)
在上篇文章《枚举和样本 - 统计随机试验(2)》中,我们通过编程枚举试验结果时用到Python的itertools库,本文进一步介绍itertools库在数据枚举中的应用。
itertools是Python标准库中的一个模块,提供了非常有用的迭代器生成函数,用于高效地处理循环和迭代操作。itertools包含了一些函数,这些函数返回的对象是迭代器,这些迭代器可以在循环中使用。下面是itertools库的一些常见函数及其运用的介绍。
常用函数
1、itertools.product(*iterables, repeat=1)
【用途】计算多个可迭代对象的笛卡尔积。
【示例代码(1)】
import itertools
prod = itertools.product('AB', '12')
print(list(prod)) # 输出: [('A', '1'), ('A', '2'), ('B', '1'), ('B', '2')]
2、itertools.permutations(iterable, r=None)
【用途】生成给定长度r的排列,如果r未指定,则默认为iterable的长度。
【示例代码(2)】
import itertools
perm = itertools.permutations('ABC', 2)
print(list(perm)) # 输出: [('A', 'B'), ('A', 'C'), ('B', 'A'), ('B', 'C'), ('C', 'A'), ('C', 'B')]
3、itertools.combinations(iterable, r)
【用途】生成给定长度r的组合。
【示例代码(3)】
import itertools
comb = itertools.combinations('ABC', 2)
print(list(comb)) # 输出: [('A', 'B'), ('A', 'C'), ('B', 'C')]
4、
itertools.combinations_with_replacement(iterable, r)
【用途】生成给定长度r的组合,允许元素重复。
【示例代码(4)】
import itertools
comb_wr = itertools.combinations_with_replacement('ABC', 2)
print(list(comb_wr)) # 输出: [('A', 'A'), ('A', 'B'), ('A', 'C'), ('B', 'B'), ('B', 'C'), ('C', 'C')]
排列和组合
排列和组合是组合数学中的两个基本概念,用于描述和计算从一组对象中选取对象的不同方式。它们在概率论、统计学、算法设计等领域有广泛的应用。
1、排列(Permutation)
排列是从n个不同元素中,任取m(m≤n,m与n均为自然数)个不同的元素按照一定的顺序排成一列,叫做从n个不同元素中取出m个元素的一个排列;从n个不同元素中取出m(m≤n)个元素的所有排列的个数,叫做从n个不同元素中取出m个元素的排列数,计算公式:
当m = n时,称为n或m的阶乘(也称为全排列),记为n!。
即,n! = n×(n-1)×(n-2)×...×2×1
排列或全排列都是不重复排列。如果可以重复,则称为可重复排列,记为n^m(m个n相乘)。
A(m, n) = n×n×n×...×n = n^m
例1、 由1,2,3,4可以组成多少个3位数?
解:根据题意每个3位数可以出现重复,属于排列问题。
第1位数有3种选择、第2、3位数都有3种选择,
3位数数量 = 4×4×4 = 4^3 = 64
枚举出64个3位数较为困难,我们可以Python的itertools模块来完成。
【itertools代码】
import itertools
numbers = [1, 2, 3, 4]
# 使用 itertools.product 生成可以重复的3位数排列
arr = list(itertools.product(numbers, repeat=3))
# 打印3位数排列结果
for data in arr:
print(data)
#输出:
#(1, 1, 1), (1, 1, 2), (1, 1, 3), (1, 1, 4), (1, 2, 1), (1, 2, 2), (1, 2, 3), (1, 2, 4),
#(1, 3, 1), (1, 3, 2), (1, 3, 3), (1, 3, 4), (1, 4, 1), (1, 4, 2), (1, 4, 3), (1, 4, 4),
#(2, 1, 1), (2, 1, 2), (2, 1, 3), (2, 1, 4), (2, 2, 1), (2, 2, 2), (2, 2, 3), (2, 2, 4),
#(2, 3, 1), (2, 3, 2), (2, 3, 3), (2, 3, 4), (2, 4, 1), (2, 4, 2), (2, 4, 3), (2, 4, 4),
#(3, 1, 1), (3, 1, 2), (3, 1, 3), (3, 1, 4), (3, 2, 1), (3, 2, 2), (3, 2, 3), (3, 2, 4),
#(3, 3, 1), (3, 3, 2), (3, 3, 3), (3, 3, 4), (3, 4, 1), (3, 4, 2), (3, 4, 3), (3, 4, 4),
#(4, 1, 1), (4, 1, 2), (4, 1, 3), (4, 1, 4), (4, 2, 1), (4, 2, 2), (4, 2, 3), (4, 2, 4),
#(4, 3, 1), (4, 3, 2), (4, 3, 3), (4, 3, 4), (4, 4, 1), (4, 4, 2), (4, 4, 3), (4, 4, 4)
例2、 由0、1,2,3,4可以组成多少个3位数?
解:根据题意,个位数和十位数的数字均无限制,都可以出现重复,在此前提下,遍历所有的三位数,然后逐一进行全排列。但是由于题意规定“第 1 位数不能为 0”,因此,在遍历三位数的过程中,第 1 位数不能选择“0”。
第1位数有4种选择、第2、3位数都有5种选择,
3位数数量 = 4×5×5 = 100
【itertools代码】
import itertools
def generate_combinations():
numbers = [0, 1, 2, 3, 4]
# 使用 itertools.product 生成可以重复的3位数排列
arr = list(itertools.product(numbers, repeat=3))
# 过滤掉首位为0的排列
valid_arr = [dt for dt in arr if dt[0] != 0]
return valid_arr
# 生成排列并打印结果
combinations = generate_combinations()
for comb in combinations:
print(comb, end=' ')
# 打印总数
print(f"\nTotal valid combinations: {len(combinations)}")
#输出
#(1, 0, 0) (1, 0, 1) (1, 0, 2) (1, 0, 3) (1, 0, 4) (1, 1, 0) (1, 1, 1) (1, 1, 2) (1, 1, 3) (1, 1, 4)
#(1, 2, 0) (1, 2, 1) (1, 2, 2) (1, 2, 3) (1, 2, 4) (1, 3, 0) (1, 3, 1) (1, 3, 2) (1, 3, 3) (1, 3, 4)
#(1, 4, 0) (1, 4, 1) (1, 4, 2) (1, 4, 3) (1, 4, 4) (2, 0, 0) (2, 0, 1) (2, 0, 2) (2, 0, 3) (2, 0, 4)
#(2, 1, 0) (2, 1, 1) (2, 1, 2) (2, 1, 3) (2, 1, 4) (2, 2, 0) (2, 2, 1) (2, 2, 2) (2, 2, 3) (2, 2, 4)
#(2, 3, 0) (2, 3, 1) (2, 3, 2) (2, 3, 3) (2, 3, 4) (2, 4, 0) (2, 4, 1) (2, 4, 2) (2, 4, 3) (2, 4, 4)
#(3, 0, 0) (3, 0, 1) (3, 0, 2) (3, 0, 3) (3, 0, 4) (3, 1, 0) (3, 1, 1) (3, 1, 2) (3, 1, 3) (3, 1, 4)
#(3, 2, 0) (3, 2, 1) (3, 2, 2) (3, 2, 3) (3, 2, 4) (3, 3, 0) (3, 3, 1) (3, 3, 2) (3, 3, 3) (3, 3, 4)
#(3, 4, 0) (3, 4, 1) (3, 4, 2) (3, 4, 3) (3, 4, 4) (4, 0, 0) (4, 0, 1) (4, 0, 2) (4, 0, 3) (4, 0, 4)
#(4, 1, 0) (4, 1, 1) (4, 1, 2) (4, 1, 3) (4, 1, 4) (4, 2, 0) (4, 2, 1) (4, 2, 2) (4, 2, 3) (4, 2, 4)
#(4, 3, 0) (4, 3, 1) (4, 3, 2) (4, 3, 3) (4, 3, 4) (4, 4, 0) (4, 4, 1) (4, 4, 2) (4, 4, 3) (4, 4, 4)
#Total valid combinations: 100
例3、 由1,2,3,4可以组成多少个不出现重复数字3位数?
解:根据题意,个、十、百位数都不能重复,为排列问题。
A(3, 4) = 4×3×2 = 24
【itertools代码】
import itertools
numbers = [1, 2, 3, 4]
# 使用 itertools.permutations 生成3位数排列
arr = list(itertools.permutations(numbers, 3))
# 打印3位数排列结果
for dt in arr:
print(dt, end=' ')
#输出:
#(1, 2, 3), (1, 2, 4), (1, 3, 2), (1, 3, 4), (1, 4, 2), (1, 4, 3), (2, 1, 3), (2, 1, 4),
#(2, 3, 1), (2, 3, 4), (2, 4, 1), (2, 4, 3), (3, 1, 2), (3, 1, 4), (3, 2, 1), (3, 2, 4),
#(3, 4, 1), (3, 4, 2), (4, 1, 2), (4, 1, 3), (4, 2, 1), (4, 2, 3), (4, 3, 1), (4, 3, 2)
2、组合(Combination)
从n个不同的元素中,任取m(m≤n)个元素为一组,叫作从n个不同元素中取出m个元素的一个组合。
组合和排列的区别是排列和顺序有关、组合和顺序无关。
不重复组合公式:
重复组合公式:
例4,由A,B,C、D排列和组合成3位字符。
【排列】A(3, 4) = 4×3×2 = 24
ABC、ABD、ACB、ACD、ADB、ADC、BAC、BAD、BCA、BCD、BDA、BDC、
CBA、CBD、CAB、CAD、CDB、CDA、ABC、ABD、ACB、ACD、ADB、ADC、
【组合】C(3, 4) = A(3, 4)/3! = 24/6=4
ABC、ABD、ACD、BCD;
【itertools组合代码】
import itertools
comb = itertools.combinations('ABCD', 3)
print(list(comb))
# 输出[('A', 'B', 'C'), ('A', 'B', 'D'), ('A', 'C', 'D'), ('B', 'C', 'D')]
例5、由A,B,C看重复组合成3位字符。
解:C(m, n+m-1) = C(3, 3+3-1) = C(3, 5) = 5×4×3/3! = 10
#共有10个重复组合字符
['A', 'A', 'A'], ['A', 'A', 'B'], ['A', 'A', 'C'], ['A', 'B', 'B'], ['A', 'B', 'C'],
['A', 'C', 'C'], ['B', 'B', 'B'], ['B', 'B', 'C'], ['B', 'C', 'C'], ['C', 'C', 'C']
【itertools重复组合代码】
import itertools
comb_wr = itertools.combinations_with_replacement('ABC', 3)
print(list(comb_wr))
print("\n")
分组排列枚举问题
在体育比赛中,分两组交叉比赛,第一组由A、B、C和D队组成,第二组由a、b、c和d队组成。两组之间随机排列打交叉赛,试排除比赛分组表。
可运用itertools模块计算多个可迭代对象的笛卡尔积。
【itertools笛卡尔积代码】
import itertools
prod = itertools.product('ABCD', 'abcd')
print(list(prod))
#输出:
#[('A', 'a'), ('A', 'b'), ('A', 'c'), ('A', 'd'), ('B', 'a'), ('B', 'b'), ('B', 'c'), ('B', 'd'),
# ('C', 'a'), ('C', 'b'), ('C', 'c'), ('C', 'd'), ('D', 'a'), ('D', 'b'), ('D', 'c'), ('D', 'd')]
itertools是python内置的模块,使用简单且功能强大,是组合数学、概率统计和模拟仿真试验的有力工具。
参考文献:
itertools官方文档地址:https://docs.python.org/zh-cn/3/library/itertools.htm
W3Cshool Python教程:https://www.w3school.com.cn/python/python_reference.asp
W3Cshool Python3在线工具:https://www.w3cschool.cn/tryrun/runcode?lang=python3