فاکتوریل ها، جایگشت ها و ترکیب ها را در پایتون محاسبه و تولید کنید

کسب و کار

ریاضیات ماژول استاندارد برای توابع ریاضی در پایتون را می توان برای محاسبه فاکتوریل استفاده کرد. 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 را به‌عنوان «from scipy.special import perm» مانند مثال بالا، یا ()scipy.special.perm را به‌عنوان «import scipy.special» اجرا کنید.

ایجاد و شمارش جایگشت از یک لیست:itertools.permutations()

نه تنها اعداد کل، بلکه جایگشت ها نیز می توانند از لیست ها (آرایه ها) و غیره تولید و شمارش شوند.

از تابع permutations() ماژول itertools استفاده کنید.

ارسال یک تکرار (نوع لیست یا مجموعه) به عنوان اولین آرگومان و تعداد قطعاتی که باید به عنوان آرگومان دوم انتخاب شوند، یک تکرار کننده برای آن جایگشت برمی گرداند.

import itertools

l = ['a', 'b', 'c', 'd']

p = itertools.permutations(l, 2)

print(type(p))
# <class 'itertools.permutations'>

برای برشمردن همه آنها می توانید از یک حلقه for استفاده کنید.

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 را بارگذاری نمی کند.

مانند مثال بالا، comb() را به صورت “from scipy.special import comb” یا ()scipy.special.comb را به صورت “import 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 استفاده کنید.

ارسال یک تکرارپذیر (نوع لیست یا مجموعه) به عنوان اولین آرگومان و تعداد قطعاتی که باید به عنوان آرگومان دوم انتخاب شوند، تکرار کننده آن ترکیب را برمی گرداند.

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 استفاده کنید.

ارسال یک تکرارپذیر (نوع لیست یا مجموعه) به عنوان اولین آرگومان و تعداد قطعاتی که باید به عنوان آرگومان دوم انتخاب شوند، یک تکرار کننده برای آن ترکیب همپوشانی برمی گرداند.

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() ایجاد جایگشت رشته (anagrams) را آسان می کند.

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() که عناصر یک لیست یا تاپل را به یک رشته متصل می کند و از نماد درک لیست استفاده می شود.

Copied title and URL