คณิตศาสตร์โมดูลมาตรฐานสำหรับฟังก์ชันทางคณิตศาสตร์ใน Python สามารถใช้คำนวณแฟกทอเรียลได้ SciPy ยังมีฟังก์ชันในการคำนวณจำนวนการเรียงสับเปลี่ยน/ชุดค่าผสมทั้งหมด
โมดูล itertools ยังสามารถใช้เพื่อสร้างพีชคณิตและการรวมจากรายการ (อาร์เรย์) ฯลฯ และแจกแจงรายการเหล่านี้
มีการอธิบายสิ่งต่อไปนี้พร้อมกับโค้ดตัวอย่าง
- แฟกทอเรียล:
math.factorial()
- คำนวณจำนวนการเรียงสับเปลี่ยนทั้งหมด
math.factorial()
scipy.special.perm()
- สร้างและแจกแจงการเรียงสับเปลี่ยนจากรายการ:
itertools.permutations()
- คำนวณจำนวนชุดค่าผสมทั้งหมด
math.factorial()
scipy.special.comb()
- วิธีไม่ใช้ math.factorial()
- สร้างและระบุชุดค่าผสมจากรายการ:
itertools.combinations()
- คำนวณจำนวนชุดค่าผสมที่ซ้ำกัน
- สร้างและระบุชุดค่าผสมที่ซ้ำกันจากรายการ:
itertools.combinations_with_replacement()
ตัวอย่างการใช้พีชคณิตจะอธิบายสิ่งต่อไปนี้ด้วย
- สร้างแอนนาแกรมจากสตริง
หากคุณต้องการสร้างองค์ประกอบหลายรายการรวมกันแทนที่จะเป็นรายการเดียว ให้ใช้ itertools.product() ในโมดูล itertools
- แฟกทอเรียล:math.factorial()
- คำนวณจำนวนการเรียงสับเปลี่ยนทั้งหมด
- สร้างและแจกแจงการเรียงสับเปลี่ยนจากรายการ:itertools.permutations()
- คำนวณจำนวนชุดค่าผสมทั้งหมด
- สร้างและระบุชุดค่าผสมจากรายการ:itertools.combinations()
- คำนวณจำนวนชุดค่าผสมที่ซ้ำกัน
- สร้างและระบุชุดค่าผสมที่ซ้ำกันจากรายการ:itertools.combinations_with_replacement()
- สร้างแอนนาแกรมจากสตริง
แฟกทอเรียล:math.factorial()
โมดูลคณิตศาสตร์จัดเตรียมฟังก์ชัน factorial() ที่คืนค่าแฟกทอเรียล
import math
print(math.factorial(5))
# 120
print(math.factorial(0))
# 1
ไม่ใช่จำนวนเต็ม ค่าลบจะส่งผลให้เกิด ValueError
# print(math.factorial(1.5))
# ValueError: factorial() only accepts integral values
# print(math.factorial(-1))
# ValueError: factorial() not defined for negative values
คำนวณจำนวนการเรียงสับเปลี่ยนทั้งหมด
math.factorial()
การเรียงสับเปลี่ยนคือจำนวนกรณีที่ r ถูกเลือกจาก n อันที่ต่างกันและวางเรียงกันเป็นแถว
จำนวนการเรียงสับเปลี่ยนทั้งหมด p ได้มาจากสมการต่อไปนี้โดยใช้แฟกทอเรียล
p = n! / (n - r)!
สามารถคำนวณได้ดังนี้โดยใช้ฟังก์ชัน math.factorial() ซึ่งจะคืนค่าแฟกทอเรียล ตัวดำเนินการ ⌘ ซึ่งทำการหารจำนวนเต็ม ใช้เพื่อส่งคืนประเภทจำนวนเต็ม
def permutations_count(n, r):
return math.factorial(n) // math.factorial(n - r)
print(permutations_count(4, 2))
# 12
print(permutations_count(4, 4))
# 24
scipy.special.perm()
SciPy จัดเตรียมฟังก์ชัน scipy.special.perm() ที่ส่งคืนจำนวนการเรียงสับเปลี่ยนทั้งหมด จำเป็นต้องมีการติดตั้ง SciPy แยกต่างหาก มีตั้งแต่เวอร์ชัน 0.14.0
from scipy.special import perm
print(perm(4, 2))
# 12.0
print(perm(4, 2, exact=True))
# 12
print(perm(4, 4, exact=True))
# 24
exact=False
อาร์กิวเมนต์ที่สามถูกตั้งค่าตามค่าเริ่มต้นและส่งคืนตัวเลขทศนิยม โปรดทราบว่าถ้าคุณต้องการให้เป็นจำนวนเต็ม คุณต้องตั้งค่าดังนี้exact=True
โปรดทราบว่าเฉพาะ “นำเข้า scipy” เท่านั้นที่จะไม่โหลดโมดูล scipy.special
ดำเนินการ perm() เป็น “จาก scipy.special import perm” ตามตัวอย่างด้านบน หรือดำเนินการ scipy.special.perm() เป็น “import scipy.special”
สร้างและแจกแจงการเรียงสับเปลี่ยนจากรายการ:itertools.permutations()
ไม่เพียงแค่จำนวนทั้งหมดเท่านั้น แต่ยังสามารถสร้างและเรียงสับเปลี่ยนได้จากรายการ (อาร์เรย์) เป็นต้น
ใช้ฟังก์ชันพีชคณิต () ของโมดูล itertools
การส่งผ่าน iterable (รายการหรือประเภทชุด) เป็นอาร์กิวเมนต์แรกและจำนวนชิ้นที่จะเลือกเป็นอาร์กิวเมนต์ที่สองจะคืนค่า iterator สำหรับการเปลี่ยนลำดับนั้น
import itertools
l = ['a', 'b', 'c', 'd']
p = itertools.permutations(l, 2)
print(type(p))
# <class 'itertools.permutations'>
ในการแจกแจงทั้งหมด คุณสามารถใช้ for loop
for v in itertools.permutations(l, 2):
print(v)
# ('a', 'b')
# ('a', 'c')
# ('a', 'd')
# ('b', 'a')
# ('b', 'c')
# ('b', 'd')
# ('c', 'a')
# ('c', 'b')
# ('c', 'd')
# ('d', 'a')
# ('d', 'b')
# ('d', 'c')
เนื่องจากเป็นตัววนซ้ำแบบจำกัด จึงสามารถแปลงเป็นประเภทรายการด้วย list()
เมื่อได้รับจำนวนองค์ประกอบในรายการด้วย len() สามารถยืนยันได้ว่าตรงกับจำนวนการเปลี่ยนแปลงทั้งหมดที่คำนวณจากแฟคทอเรียล
p_list = list(itertools.permutations(l, 2))
print(p_list)
# [('a', 'b'), ('a', 'c'), ('a', 'd'), ('b', 'a'), ('b', 'c'), ('b', 'd'), ('c', 'a'), ('c', 'b'), ('c', 'd'), ('d', 'a'), ('d', 'b'), ('d', 'c')]
print(len(p_list))
# 12
หากละเว้นอาร์กิวเมนต์ที่สอง การเรียงสับเปลี่ยนสำหรับการเลือกองค์ประกอบทั้งหมดจะถูกส่งคืน
for v in itertools.permutations(l):
print(v)
# ('a', 'b', 'c', 'd')
# ('a', 'b', 'd', 'c')
# ('a', 'c', 'b', 'd')
# ('a', 'c', 'd', 'b')
# ('a', 'd', 'b', 'c')
# ('a', 'd', 'c', 'b')
# ('b', 'a', 'c', 'd')
# ('b', 'a', 'd', 'c')
# ('b', 'c', 'a', 'd')
# ('b', 'c', 'd', 'a')
# ('b', 'd', 'a', 'c')
# ('b', 'd', 'c', 'a')
# ('c', 'a', 'b', 'd')
# ('c', 'a', 'd', 'b')
# ('c', 'b', 'a', 'd')
# ('c', 'b', 'd', 'a')
# ('c', 'd', 'a', 'b')
# ('c', 'd', 'b', 'a')
# ('d', 'a', 'b', 'c')
# ('d', 'a', 'c', 'b')
# ('d', 'b', 'a', 'c')
# ('d', 'b', 'c', 'a')
# ('d', 'c', 'a', 'b')
# ('d', 'c', 'b', 'a')
print(len(list(itertools.permutations(l))))
# 24
ใน itertools.permutations() องค์ประกอบจะได้รับการปฏิบัติตามตำแหน่ง ไม่ใช่ค่า ค่าที่ซ้ำกันจะไม่ถูกนำมาพิจารณา
l = ['a', 'a']
for v in itertools.permutations(l, 2):
print(v)
# ('a', 'a')
# ('a', 'a')
เช่นเดียวกับฟังก์ชันต่อไปนี้ที่อธิบายไว้ด้านล่าง
itertools.combinations()
itertools.combinations_with_replacement()
คำนวณจำนวนชุดค่าผสมทั้งหมด
math.factorial()
จำนวนชุดค่าผสมคือจำนวน r ชิ้นเพื่อเลือกจาก n ชิ้นที่แตกต่างกัน ลำดับไม่ถือว่าเป็นการเรียงสับเปลี่ยน
จำนวนรวมของชุดค่าผสม c ได้มาจากสมการต่อไปนี้
c = n! / (r! * (n - r)!)
สามารถคำนวณได้ดังนี้โดยใช้ฟังก์ชัน math.factorial() ซึ่งจะคืนค่าแฟกทอเรียล ตัวดำเนินการ ⌘ ซึ่งทำการหารจำนวนเต็ม ใช้เพื่อส่งคืนประเภทจำนวนเต็ม
def combinations_count(n, r):
return math.factorial(n) // (math.factorial(n - r) * math.factorial(r))
print(combinations_count(4, 2))
# 6
scipy.special.comb()
SciPy จัดเตรียมฟังก์ชัน scipy.special.comb() ที่ส่งคืนจำนวนการเรียงสับเปลี่ยนทั้งหมด จำเป็นต้องมีการติดตั้ง SciPy แยกต่างหาก มีตั้งแต่เวอร์ชัน 0.14.0 โปรดทราบว่า scipy.misc.comb() ไม่ได้ใช้การทำซ้ำอาร์กิวเมนต์ที่อธิบายไว้ด้านล่าง
from scipy.special import comb
print(comb(4, 2))
# 6.0
print(comb(4, 2, exact=True))
# 6
print(comb(4, 0, exact=True))
# 1
exact=False
เช่นเดียวกับ scipy.special.perm() อาร์กิวเมนต์ที่สามจะถูกตั้งค่าตามค่าเริ่มต้นและส่งกลับค่าทศนิยม โปรดทราบว่าถ้าคุณต้องการให้เป็นจำนวนเต็ม คุณต้องตั้งค่าดังนี้exact=True
จำนวนรวมของชุดค่าผสมที่ซ้ำกันสามารถรับได้ด้วยอาร์กิวเมนต์ที่สี่ การทำซ้ำ สิ่งนี้อธิบายไว้ด้านล่าง
ย้ำอีกครั้งว่าเฉพาะ “นำเข้า scipy” เท่านั้นที่จะไม่โหลดโมดูล scipy.special
ดังในตัวอย่างข้างต้น เรียกใช้งานหวี () เป็น “จากหวีนำเข้า scipy.special” หรือดำเนินการ scipy.special.comb() เป็น “นำเข้า scipy.special” เช่นเดียวกับ “scipy.misc”
วิธีไม่ใช้ math.factorial()
อีกวิธีหนึ่งที่ใช้เฉพาะไลบรารีมาตรฐานและเร็วกว่าวิธีที่ใช้ math.factorial() คือวิธีการดังต่อไปนี้
from operator import mul
from functools import reduce
def combinations_count(n, r):
r = min(r, n - r)
numer = reduce(mul, range(n, n - r, -1), 1)
denom = reduce(mul, range(1, r + 1), 1)
return numer // denom
print(combinations_count(4, 2))
# 6
print(combinations_count(4, 0))
# 1
สร้างและระบุชุดค่าผสมจากรายการ:itertools.combinations()
เป็นไปได้ที่จะสร้างและแจกแจงชุดค่าผสมทั้งหมดจากรายการ (อาร์เรย์) ฯลฯ รวมทั้งจำนวนทั้งหมด
ใช้ฟังก์ชัน combinations() ของโมดูล itertools
การส่งผ่าน iterable (รายการหรือประเภทชุด) เป็นอาร์กิวเมนต์แรกและจำนวนชิ้นที่จะเลือกเป็นอาร์กิวเมนต์ที่สองจะคืนค่า iterator สำหรับชุดค่าผสมนั้น
l = ['a', 'b', 'c', 'd']
c = itertools.combinations(l, 2)
print(type(c))
# <class 'itertools.combinations'>
for v in itertools.combinations(l, 2):
print(v)
# ('a', 'b')
# ('a', 'c')
# ('a', 'd')
# ('b', 'c')
# ('b', 'd')
# ('c', 'd')
c_list = list(itertools.combinations(l, 2))
print(c_list)
# [('a', 'b'), ('a', 'c'), ('a', 'd'), ('b', 'c'), ('b', 'd'), ('c', 'd')]
print(len(c_list))
# 6
คำนวณจำนวนชุดค่าผสมที่ซ้ำกัน
จำนวนชุดค่าผสมที่ซ้ำกันคือจำนวนกรณีที่ r ถูกเลือกจาก n ชุดค่าผสมที่แตกต่างกัน เพื่อให้สามารถทำซ้ำได้
จำนวนชุดค่าผสมที่ซ้ำกันทั้งหมดเท่ากับจำนวนชุดค่าผสมที่เลือก (r) จาก (n + r – 1) ชุดค่าผสมที่แตกต่างกัน
ดังนั้นเราจึงสามารถใช้ฟังก์ชันที่กำหนดไว้ด้านบนเพื่อคำนวณจำนวนชุดค่าผสมทั้งหมดได้
def combinations_with_replacement_count(n, r):
return combinations_count(n + r - 1, r)
print(combinations_with_replacement_count(4, 2))
# 10
ใน “scipy.special.comb()” ที่อธิบายข้างต้น จำนวนชุดค่าผสมที่ซ้ำกันทั้งหมดสามารถรับได้โดยการตั้งค่าอาร์กิวเมนต์ที่สี่ “repetition=True
โปรดทราบว่าอาร์กิวเมนต์ “repetition” จะไม่ถูกนำมาใช้ใน “scipy.misc.comb()” ในเวอร์ชันก่อนหน้า “SciPy0.14.0”
from scipy.special import comb
print(comb(4, 2, exact=True, repetition=True))
# 10
สร้างและระบุชุดค่าผสมที่ซ้ำกันจากรายการ:itertools.combinations_with_replacement()
เป็นไปได้ที่จะสร้างและระบุชุดค่าผสมที่ซ้ำกันทั้งหมดจากรายการ (อาร์เรย์) ฯลฯ รวมทั้งจำนวนทั้งหมด
ใช้ฟังก์ชัน combinations_with_replacement() ในโมดูล itertools
การส่งผ่าน iterable (รายการหรือประเภทชุด) เป็นอาร์กิวเมนต์แรกและจำนวนชิ้นที่จะเลือกเป็นอาร์กิวเมนต์ที่สองจะคืนค่า iterator สำหรับชุดค่าผสมที่ทับซ้อนกันนั้น
h = itertools.combinations_with_replacement(l, 2)
print(type(h))
# <class 'itertools.combinations_with_replacement'>
for v in itertools.combinations_with_replacement(l, 2):
print(v)
# ('a', 'a')
# ('a', 'b')
# ('a', 'c')
# ('a', 'd')
# ('b', 'b')
# ('b', 'c')
# ('b', 'd')
# ('c', 'c')
# ('c', 'd')
# ('d', 'd')
h_list = list(itertools.combinations_with_replacement(l, 2))
print(h_list)
# [('a', 'a'), ('a', 'b'), ('a', 'c'), ('a', 'd'), ('b', 'b'), ('b', 'c'), ('b', 'd'), ('c', 'c'), ('c', 'd'), ('d', 'd')]
print(len(h_list))
# 10
สร้างแอนนาแกรมจากสตริง
Itertools.permutations() ทำให้ง่ายต่อการสร้างการเปลี่ยนลำดับสตริง (แอนนาแกรม)
s = 'arc'
for v in itertools.permutations(s):
print(v)
# ('a', 'r', 'c')
# ('a', 'c', 'r')
# ('r', 'a', 'c')
# ('r', 'c', 'a')
# ('c', 'a', 'r')
# ('c', 'r', 'a')
ในการรวมทูเพิลของอักขระหนึ่งตัวในแต่ละครั้งเข้ากับสตริงและทำให้เป็นรายการ ให้ทำดังต่อไปนี้
anagram_list = [''.join(v) for v in itertools.permutations(s)]
print(anagram_list)
# ['arc', 'acr', 'rac', 'rca', 'car', 'cra']
วิธีการ join() ซึ่งเชื่อมองค์ประกอบของ list หรือ tuple เข้ากับสตริง และใช้ list comprehension notation
- ที่เกี่ยวข้อง:การต่อสตริง (การรวม) ใน Python
- ที่เกี่ยวข้อง:วิธีใช้ Python list comprehensions