คำนวณและสร้างแฟกทอเรียล พีชคณิต และการรวมกันใน Python

ธุรกิจ

คณิตศาสตร์โมดูลมาตรฐานสำหรับฟังก์ชันทางคณิตศาสตร์ใน 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()

โมดูลคณิตศาสตร์จัดเตรียมฟังก์ชัน 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

Copied title and URL