Python itertools库介绍 - 统计随机试验(3)

liftword2个月前 (02-05)技术文章25

在上篇文章《枚举和样本 - 统计随机试验(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

相关文章

掌握Python中choice函数的用法:随机选择与random模块

知识星球:写代码那些事如果你有收获|欢迎|点赞|关注|转发这里会定期更新|大厂的开发|架构|方案设计这里也会更新|如何摸鱼|抓虾Python教程:Python中choice函数用法欢迎来到写代码那些事...

Python生成随机数_python生成随机数并判断奇偶

生成一个Python随机数 6 分钟阅读Python有一个内置的随机模块来实现此目的。它公开了几个方法,如randrange(),randint(),random(),seed(),uniform()...

Python获取随机数方法汇总_python语言如何获取随机整数

1. random.random()作用:随机生成一个[0,1)之间的浮点数import random print(f'随机生成一个[0,1)之间的浮点数={random.random()}')2....

Python 随机字符串_python 生成随机字符

在很多时候我们可能需要生成一些随机字符串。Python 也为我们提供了生成随机字符串的方法和函数。这个函数是在 random 库中定义的函数 choice。通常 choice 将会从给定的字符串中挑选...

python中随机模块random的用法_pythonrandom随机数的用法

Python 有一个可用于制作随机数的内建模块。现在总结归纳一下,方便大家查询学习random 模块有一组如下的方法:序号方法描述1seed()初始化随机数生成器。2getstate()返回随机数生成...

Python实现随机&批量梯度下降算法

一.概述梯度下降属于迭代法的一种,可以用于求解最小二乘问题。在求解机器学习算法的模型参数时,梯度下降(Gradient Descent)是最常采用的方法之一,另一种常用的方法是最小二乘法。在求解损失函...