Python’da faktöriyelleri, permütasyonları ve kombinasyonları hesaplayın ve oluşturun

Python’daki matematiksel fonksiyonlar için standart modül matematiği, faktöriyelleri hesaplamak için kullanılabilir. SciPy ayrıca toplam permütasyon/kombinasyon sayısını hesaplama işlevlerine de sahiptir.

itertools modülü, listelerden (diziler) vb. permütasyonlar ve kombinasyonlar oluşturmak ve bunları numaralandırmak için de kullanılabilir.

Aşağıda örnek kodla birlikte burada açıklanmıştır.

  • faktöriyel:math.factorial()
  • Toplam permütasyon sayısını hesaplayın
    • math.factorial()
    • scipy.special.perm()
  • Bir listeden permütasyonlar oluşturun ve numaralandırın:itertools.permutations()
  • Toplam kombinasyon sayısını hesaplayın
    • math.factorial()
    • scipy.special.comb()
    • Math.factorial() nasıl kullanılmaz?
  • Listelerden kombinasyonlar oluşturun ve numaralandırın:itertools.combinations()
  • Yinelenen kombinasyonların toplam sayısını hesaplayın
  • Bir listeden yinelenen kombinasyonlar oluşturun ve numaralandırın:itertools.combinations_with_replacement()

Permütasyon kullanımına bir örnek olarak aşağıdakiler de açıklanmıştır.

  • Dizelerden anagramlar oluşturun

Tek bir liste yerine birden çok listenin öğelerinin bir kombinasyonunu oluşturmak istiyorsanız, itertools modülünde itertools.product() öğesini kullanın.

faktöriyel:math.factorial()

Matematik modülü, faktöriyel değeri döndüren bir factorial() işlevi sağlar.

import math

print(math.factorial(5))
# 120

print(math.factorial(0))
# 1

Tamsayı olmayan, negatif değerler ValueError ile sonuçlanacaktır.

# print(math.factorial(1.5))
# ValueError: factorial() only accepts integral values

# print(math.factorial(-1))
# ValueError: factorial() not defined for negative values

Toplam permütasyon sayısını hesaplayın

math.factorial()

Permütasyonlar, r’nin n farklı olandan seçildiği ve arka arkaya yerleştirildiği durumların sayısıdır.

Toplam permütasyon sayısı, p, faktöriyeller kullanılarak aşağıdaki denklemle elde edilir.

p = n! / (n - r)!

Faktöriyel değeri döndüren math.factorial() işlevi kullanılarak aşağıdaki gibi hesaplanabilir. Tamsayı bölme işlemini gerçekleştiren ⌘ operatörü, bir tamsayı tipi döndürmek için kullanılır.

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.özel.perm()

SciPy, toplam permütasyon sayısını döndüren bir scipy.special.perm() işlevi sağlar. Ayrı bir SciPy kurulumu gereklidir. 0.14.0 sürümünden itibaren mevcuttur.

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
Üçüncü argüman, varsayılan olarak yukarıdaki gibi ayarlanır ve bir kayan noktalı sayı döndürür. Bir tamsayı olarak almak istiyorsanız, aşağıdaki gibi ayarlamanız gerektiğini unutmayın.
exact=True

Yalnızca “import scipy”nin scipy.special modülünü yüklemeyeceğini unutmayın.

perm()’i yukarıdaki örnekte olduğu gibi “from scipy.special ithalat izni” olarak yürütün veya scipy.special.perm()’i “import scipy.special” olarak yürütün.

Bir listeden permütasyonlar oluşturun ve numaralandırın:itertools.permutations()

Yalnızca toplam sayılar değil, aynı zamanda permütasyonlar da oluşturulabilir ve listelerden (diziler) vb.

itertools modülünün permutations() işlevini kullanın.

İlk argüman olarak bir yinelenebilir (liste veya set tipi) ve ikinci argüman olarak seçilecek parça sayısı iletmek, o permütasyon için bir yineleyici döndürür.

import itertools

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

p = itertools.permutations(l, 2)

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

Hepsini sıralamak için bir for döngüsü kullanabilirsiniz.

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')

Sonlu bir yineleyici olduğu için list() ile bir liste tipine de dönüştürülebilir.

Listedeki eleman sayısı len() ile elde edildiğinde, faktöriyelden hesaplanan toplam permütasyon sayısı ile eşleştiği doğrulanabilir.

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

İkinci argüman atlanırsa, tüm öğeleri seçme permütasyonu döndürülür.

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() içinde, öğeler değere göre değil, konuma göre işlenir. Yinelenen değerler dikkate alınmaz.

l = ['a', 'a']

for v in itertools.permutations(l, 2):
    print(v)
# ('a', 'a')
# ('a', 'a')

Aynısı aşağıda açıklanan aşağıdaki işlevler için de geçerlidir.

  • itertools.combinations()
  • itertools.combinations_with_replacement()

Toplam kombinasyon sayısını hesaplayın

math.factorial()

Kombinasyon sayısı, n farklı parça arasından seçilecek r parça sayısıdır. Sıra, permütasyonlarda olduğu gibi kabul edilmez.

Toplam kombinasyon sayısı c aşağıdaki denklemle elde edilir.

c = n! / (r! * (n - r)!)

Faktöriyel değeri döndüren math.factorial() işlevi kullanılarak aşağıdaki gibi hesaplanabilir. Tamsayı bölme işlemini gerçekleştiren ⌘ operatörü, bir tamsayı tipi döndürmek için kullanılır.

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, toplam permütasyon sayısını döndüren bir scipy.special.comb() işlevi sağlar. Ayrı bir SciPy kurulumu gereklidir. 0.14.0 sürümünden itibaren mevcuttur. scipy.misc.comb() öğesinin aşağıda açıklanan argüman tekrarını uygulamadığını unutmayın.

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() ile olduğu gibi, üçüncü argüman varsayılan olarak yukarıdaki gibi ayarlanır ve bir kayan noktalı sayı döndürür. Bir tamsayı olarak almak istiyorsanız, aşağıdaki gibi ayarlamanız gerektiğini unutmayın.
exact=True
Yinelenen kombinasyonların toplam sayısı, dördüncü argüman olan tekrar ile de elde edilebilir. Bu aşağıda açıklanmıştır.

Yine, yalnızca “import scipy”nin scipy.special modülünü yüklemeyeceğini unutmayın.

Yukarıdaki örnekte olduğu gibi, tarak()’ı “scipy.special içe aktarma tarakından” yürütün veya scipy.special.comb()’u “import scipy.special” olarak yürütün. Aynısı “scipy.misc” için de geçerlidir.

Math.factorial() nasıl kullanılmaz?

Yalnızca standart kitaplığı kullanan ve math.factorial() yöntemini kullanan yöntemden daha hızlı olan başka bir yöntem aşağıdaki yöntemdir.

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

Listelerden kombinasyonlar oluşturun ve numaralandırın:itertools.combinations()

Toplam sayıların yanı sıra listelerden (dizilerden) vb. tüm kombinasyonları oluşturmak ve numaralandırmak mümkündür.

itertools modülünün kombinasyonları() işlevini kullanın.

İlk argüman olarak bir yinelenebilir (liste veya set tipi) ve ikinci argüman olarak seçilecek parça sayısı iletmek, o kombinasyon için yineleyiciyi döndürür.

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

Yinelenen kombinasyonların toplam sayısını hesaplayın

Yinelenen kombinasyonların sayısı, r’nin n farklı kombinasyondan seçildiği ve yinelemelere izin verildiği durumların sayısıdır.

Yinelenen kombinasyonların toplam sayısı, (n + r – 1) farklı kombinasyonlardan (r) seçilecek kombinasyonların sayısına eşittir.

Bu nedenle, toplam kombinasyon sayısını hesaplamak için yukarıda tanımlanan işlevi kullanabiliriz.

def combinations_with_replacement_count(n, r):
    return combinations_count(n + r - 1, r)

print(combinations_with_replacement_count(4, 2))
# 10

Yukarıda açıklanan “scipy.special.comb()” içinde, dördüncü bağımsız değişken “repetition=True” ayarlanarak yinelenen kombinasyonların toplam sayısı elde edilebilir.
“SciPy0.14.0” öncesi sürümlerde “tekrar” argümanının “scipy.misc.comb()” içinde uygulanmadığını unutmayın.

from scipy.special import comb
print(comb(4, 2, exact=True, repetition=True))
# 10

Bir listeden yinelenen kombinasyonlar oluşturun ve numaralandırın:itertools.combinations_with_replacement()

Toplam sayıların yanı sıra listelerden (dizilerden) vb. tüm yinelenen kombinasyonları oluşturmak ve numaralandırmak mümkündür.

itertools modülündeki kombinasyonlar_with_replacement() işlevini kullanın.

İlk argüman olarak bir yinelenebilir (liste veya set tipi) ve ikinci argüman olarak seçilecek parça sayısı iletmek, bu örtüşen kombinasyon için bir yineleyici döndürür.

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

Dizelerden anagramlar oluşturun

Itertools.permutations(), dize permütasyonları (anagramlar) oluşturmayı kolaylaştırır.

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')

Bir kerede bir karakterden oluşan bir demeti bir dizgede birleştirmek ve bir liste haline getirmek için aşağıdakileri yapın.

anagram_list = [''.join(v) for v in itertools.permutations(s)]

print(anagram_list)
# ['arc', 'acr', 'rac', 'rca', 'car', 'cra']

Bir listenin veya tanımlama grubunun öğelerini bir dizede birleştiren join() yöntemi ve liste anlama gösterimi kullanılır.