A Pythonban a matematikai függvények standard math modulja használható a faktoriálisok kiszámítására. A SciPy rendelkezik olyan függvényekkel is, amelyekkel kiszámítható a permutációk\kombinációk teljes száma.
Az itertools modul arra is használható, hogy listákból (tömbökből) stb. permutációkat és kombinációkat hozzon létre, és azokat felsorolja.
A következőket itt magyarázzuk el, mintakóddal együtt.
- faktoriális:
math.factorial()
- A permutációk teljes számának kiszámítása
math.factorial()
scipy.special.perm()
- Permutációk generálása és felsorolása egy listából:
itertools.permutations()
- Számítsa ki a kombinációk teljes számát
math.factorial()
scipy.special.comb()
- Hogyan ne használjuk a math.factorial()
- Kombinációk generálása és felsorolása listákból:
itertools.combinations()
- A duplikált kombinációk teljes számának kiszámítása
- Duplikált kombinációk generálása és felsorolása egy listából:
itertools.combinations_with_replacement()
A permutációk felhasználásának példájaként a következőt is elmagyarázzuk.
- Anagrammák létrehozása karakterláncokból
Ha egyetlen lista helyett több lista elemeinek kombinációját szeretné létrehozni, használja az itertools.product() funkciót az itertools modulban.
- faktoriális: math.factorial()
- A permutációk teljes számának kiszámítása
- Permutációk generálása és felsorolása egy listából: itertools.permutations()
- Számítsa ki a kombinációk teljes számát
- Kombinációk generálása és felsorolása listákból: itertools.combinations()
- A duplikált kombinációk teljes számának kiszámítása
- Duplikált kombinációk generálása és felsorolása egy listából: itertools.combinations_with_replacement()
- Anagrammák létrehozása karakterláncokból
faktoriális: math.factorial()
A matematikai modul biztosít egy factorial() függvényt, amely visszaadja a faktoriált.
import math
print(math.factorial(5))
# 120
print(math.factorial(0))
# 1
A nem egész, negatív értékek ValueError-t eredményeznek.
# print(math.factorial(1.5))
# ValueError: factorial() only accepts integral values
# print(math.factorial(-1))
# ValueError: factorial() not defined for negative values
A permutációk teljes számának kiszámítása
math.factorial()
Permutációknak nevezzük azoknak az eseteknek a számát, amikor r-et választunk n különbözőből, és egy sorba helyezzük.
A permutációk teljes számát, p-t, a következő egyenlet segítségével kapjuk meg a faktoriálisok segítségével.
p = n! / (n - r)!
A következőképpen számítható ki a math.factorial() függvény segítségével, amely visszaadja a faktoriális értéket. A ⌘ operátorral, amely egész szám osztást végez, egész szám típusú értéket ad vissza.
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()
A SciPy biztosít egy scipy.special.perm() függvényt, amely a permutációk teljes számát adja vissza. Külön SciPy telepítés szükséges hozzá. Elérhető a 0.14.0 verziójától.
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
A harmadik argumentum alapértelmezés szerint a fentiek szerint van beállítva, és egy lebegőpontos számot ad vissza. Vegye figyelembe, hogy ha egész számként szeretné megkapni, akkor a következőképpen kell beállítania.exact=True
Vegyük észre, hogy csak az “import scipy” nem tölti be a scipy.special modult.
A perm() végrehajtása “from scipy.special import perm”, mint a fenti példában, vagy a scipy.special.perm() végrehajtása “import scipy.special”.
Permutációk generálása és felsorolása egy listából: itertools.permutations()
Nemcsak az összes számok, hanem a permutációk is generálhatók és felsorolhatók listákból (tömbökből) stb.
Használja az itertools modul permutations() függvényét.
Egy iterábilis (lista vagy halmaz típus) átadása első argumentumként és a kiválasztandó darabok száma második argumentumként egy iterátort ad vissza az adott permutációhoz.
import itertools
l = ['a', 'b', 'c', 'd']
p = itertools.permutations(l, 2)
print(type(p))
# <class 'itertools.permutations'>
Ha mindet fel akarja sorolni, használhat egy for-hurkot.
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')
Mivel ez egy véges iterátor, a list() segítségével listává is konvertálható.
Ha a len() segítségével megkapjuk a lista elemeinek számát, megerősíthetjük, hogy az megegyezik a faktoriálisból számított összes permutáció számával.
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
Ha a második argumentum kimarad, akkor az összes elem kiválasztására szolgáló permutáció kerül visszaadásra.
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
Az itertools.permutations()-ban az elemek kezelése a pozíció, nem pedig az érték alapján történik. A duplikált értékeket nem veszi figyelembe.
l = ['a', 'a']
for v in itertools.permutations(l, 2):
print(v)
# ('a', 'a')
# ('a', 'a')
Ugyanez vonatkozik a következő, alább ismertetett funkciókra is.
itertools.combinations()
itertools.combinations_with_replacement()
Számítsa ki a kombinációk teljes számát
math.factorial()
A kombinációk száma az n különböző darabból választható r darabok száma. A sorrendet nem vesszük figyelembe, mint a permutációkban.
A c kombinációk teljes számát a következő egyenlet alapján kapjuk meg.
c = n! / (r! * (n - r)!)
A következőképpen számítható ki a math.factorial() függvény segítségével, amely visszaadja a faktoriális értéket. A ⌘ operátorral, amely egész szám osztást végez, egész szám típusú értéket ad vissza.
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()
A SciPy biztosít egy scipy.special.comb() függvényt, amely a permutációk teljes számát adja vissza. Külön SciPy telepítés szükséges hozzá. Elérhető a 0.14.0 verziójától. Vegyük észre, hogy a scipy.misc.comb() nem valósítja meg az alább leírt argumentumismétlést.
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
Ahogy a scipy.special.perm() esetében is, a harmadik argumentum alapértelmezés szerint a fentiek szerint van beállítva, és egy lebegőpontos számot ad vissza. Vegyük észre, hogy ha egész számként szeretnénk megkapni, akkor a következőképpen kell beállítanunk.exact=True
A duplikált kombinációk teljes számát a negyedik argumentummal, az ismétléssel is meg lehet kapni. Ezt az alábbiakban ismertetjük.
Ismét megjegyezzük, hogy csak az “import scipy” nem tölti be a scipy.special modult.
A fenti példához hasonlóan a comb() parancsot a “from scipy.special import comb” vagy a scipy.special.comb() parancsot az “import scipy.special” parancsként kell végrehajtani. Ugyanez vonatkozik a “scipy.misc” parancsra is.
Hogyan ne használjuk a math.factorial()
Egy másik módszer, amely csak a szabványos könyvtárat használja, és gyorsabb, mint a math.factorial() módszer, a következő módszer.
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
Kombinációk generálása és felsorolása listákból: itertools.combinations()
Lehetőség van a listákból (tömbökből) stb. származó összes kombináció, valamint a teljes számok generálására és felsorolására.
Használja az itertools modul combinations() függvényét.
Egy iterábilis (lista vagy halmaz típus) átadása első argumentumként és a kiválasztandó darabok száma második argumentumként az adott kombinációhoz tartozó iterátort adja vissza.
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
A duplikált kombinációk teljes számának kiszámítása
A duplikált kombinációk száma azoknak az eseteknek a száma, amelyekben r-t választunk n különböző kombináció közül, figyelembe véve a duplikációkat.
A duplikált kombinációk teljes száma megegyezik az (n + r – 1) különböző kombinációk közül választható (r) kombinációk számával.
Ezért a fent meghatározott függvényt használhatjuk a kombinációk teljes számának kiszámítására.
def combinations_with_replacement_count(n, r):
return combinations_count(n + r - 1, r)
print(combinations_with_replacement_count(4, 2))
# 10
A fent leírt “scipy.special.comb()”-ban a duplikált kombinációk teljes számát a negyedik argumentum “repetition=True” beállításával kaphatjuk meg.
Vegye figyelembe, hogy az “ismétlés” argumentum a “SciPy0.14.0” előtti verziókban nincs implementálva a “scipy.misc.comb()”-ban.
from scipy.special import comb
print(comb(4, 2, exact=True, repetition=True))
# 10
Duplikált kombinációk generálása és felsorolása egy listából: itertools.combinations_with_replacement()
Lehetőség van az összes duplikált kombináció generálására és felsorolására listákból (tömbökből) stb., valamint az összesített számokból.
Használja az itertools modul combinations_with_replacement() függvényét.
Egy iterábilis (lista vagy halmaz típus) átadása első argumentumként és a kiválasztandó darabok száma második argumentumként egy iterátort ad vissza az adott átfedő kombinációhoz.
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
Anagrammák létrehozása karakterláncokból
Az Itertools.permutations() segítségével könnyen létrehozhatunk karakterlánc-permutációkat (anagrammákat).
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')
Egyszerre egy karaktert tartalmazó tuple-t egy karakterlánccá kombinálunk, és listává alakítjuk, a következőképpen járunk el
anagram_list = [''.join(v) for v in itertools.permutations(s)]
print(anagram_list)
# ['arc', 'acr', 'rac', 'rca', 'car', 'cra']
A join() metódus, amely egy lista vagy tuple elemeit egy karakterlánccá fűzi össze, és a lista megértésének jelölése használatos.