Python'da Faktöriyel Fonksiyon


135

Python'da bir tamsayının faktöriyelini nasıl hesaplayabilirim?

Yanıtlar:


191

Kullanmanın en kolay yolu math.factorial(Python 2.6 ve üzeri sürümlerde mevcuttur):

import math
math.factorial(1000)

Kendiniz yazmak istiyorsanız / yinelemek istiyorsanız, yinelemeli bir yaklaşım kullanabilirsiniz:

def factorial(n):
    fact = 1
    for num in range(2, n + 1):
        fact *= num
    return fact

veya özyinelemeli bir yaklaşım:

def factorial(n):
    if n < 2:
        return 1
    else:
        return n * factorial(n-1)

O Not faktöryel fonksiyonu da kontrol etmelisiniz böylece sadece pozitif tamsayılar için tanımlanan n >= 0ve bu isinstance(n, int). Değilse, sırasıyla bir ValueErrorveya bir yükseltin TypeError. math.factorialbunun için seninle ilgilenecek.


2
Ne nasıl kullanabileceğinizi anlayamıyorum factorialiçindefactorialİşlev . Aynı işlevi tanımladığınız işlev içinde nasıl kullanabilirsiniz? Python'da yeniyim, bu yüzden anlamaya çalışıyorum.
J82

8
@ J82: Burada kullanılan konsepte özyineleme denir ( en.wikipedia.org/wiki/Recursion_(computer_science) ) - kendini çağıran bir işlev mükemmel derecede iyi ve genellikle yararlıdır.
schnaader

Python'un yineleme sınırını artırmazsanız , yinelemeli işlev RecursionError998'den (dener factorial(999)) daha büyük bir sayı için bir yükseltir
Boris

114

Python 2.6 ve sonraki sürümlerde şunları deneyin:

import math
math.factorial(n)

Python 3.9 ile başlayarak , floatbu fonksiyona a geçilmesi a'yı yükseltir DeprecationWarning. Bunu yapmak istiyorsanız, açık nbir intşekilde dönüştürmeniz gerekir : math.factorial(int(n))ondalıktan sonra herhangi bir şeyi atacak, bu yüzden bunu kontrol etmek isteyebilirsinizn.is_integer()
Boris

25

Bu çok eski bir iplik olduğu için gerçekten gerekli değil. Ama burada bir while döngüsü kullanarak bir tamsayının faktöriyel hesaplamak için başka bir yol yaptım.

def factorial(n):
    num = 1
    while n >= 1:
        num = num * n
        n = n - 1
    return num

4
faktöriyel (-1) 1 döndürür, ValueError veya başka bir şeyi yükseltmelidir.
f.rodrigues

Ondalıktan sonra sayı içeren bir kayan noktaya geçerseniz bu işlev yanlış sonuçlar verir.
Boris

Bu işlevle, ilk dört tamsayının faktöriyelini yazdırmak istiyorum. num = num * nSatır konumu ile birlikte takas ettiğimde n = n - 1ve çalıştırdığımda for i in range(1, 5): print('Factorial of', i, 'is', factorial(i))Her Faktöriyör için çıktı 0'dır num = num * n. Neden önce gelmek gerektiğinin mantığını bilmek istiyorum . Teşekkürler!!

18

Mevcut çözüm

En kısa ve muhtemelen en hızlı çözüm:

from math import factorial
print factorial(1000)

Kendinizinkini oluşturun

Kendi çözümünüzü de oluşturabilirsiniz. Genellikle iki yaklaşımınız vardır. Bana en uygun olanı:

from itertools import imap
def factorial(x):
    return reduce(long.__mul__, imap(long, xrange(1, x + 1)))

print factorial(1000)

(sonuç olduğunda daha büyük sayılar için de çalışır long)

Aynısını başarmanın ikinci yolu:

def factorial(x):
    result = 1
    for i in xrange(2, x + 1):
        result *= i
    return result

print factorial(1000)


5

Python2.5 veya daha eski bir sürümünü kullanıyorsanız

from operator import mul
def factorial(n):
    return reduce(mul, range(1,n+1))

daha yeni Python için, burada diğer cevaplarda verildiği gibi matematik modülünde faktöryel var


Bu sadece bir Python 2 cevabıdır, reducePython 3'ten kaldırılmıştır.
Boris

@Boris, Python3'te eklemeniz yeterlifrom functools import reduce
John La Rooy

Bir nedenden dolayı kaldırıldı, kullanmamalısınız artima.com/weblogs/viewpost.jsp?thread=98196
Boris

5
def fact(n):
    f = 1
    for i in range(1, n + 1):
        f *= i
    return f

4

Bir- fordöngü kullanarak , geriye doğru sayarak n:

def factorial(n):
    base = 1
    for i in range(n, 0, -1):
        base = base * i
    print(base)

3

Performans nedeniyle, lütfen özyineleme kullanmayın. Felaket olur.

def fact(n, total=1):
    while True:
        if n == 1:
            return total
        n, total = n - 1, total * n

Çalışan sonuçları kontrol edin

cProfile.run('fact(126000)')

4 function calls in 5.164 seconds

Yığını kullanmak uygundur (özyinelemeli çağrı gibi), ancak bir bedeli vardır: ayrıntılı bilgilerin depolanması çok fazla bellek alabilir.

Yığın yüksekse, bilgisayarın işlev çağrıları hakkında birçok bilgi depoladığı anlamına gelir.

Yöntem yalnızca sabit belleği (yineleme gibi) alır.

Veya döngü için kullanma

def fact(n):
    result = 1
    for i in range(2, n + 1):
        result *= i
    return result

Çalışan sonuçları kontrol edin

cProfile.run('fact(126000)')

4 function calls in 4.708 seconds

Veya Yerleşik işlev matematiğini kullanma

def fact(n):
    return math.factorial(n)

Çalışan sonuçları kontrol edin

cProfile.run('fact(126000)')

5 function calls in 0.272 seconds

1
Bence bu döngü biraz daha temiz görünüyor <! - dil: python -> def gerçeği (n): ret = 1 ise n> 1: n, ret = n - 1, ret * n dönüş ret
edilio

1
def factorial(n):
    result = 1
    i = n * (n -1)
    while n >= 1:
        result = result * n
        n = n - 1
    return result

print (factorial(10)) #prints 3628800

1

İşte benim denemem

>>> import math
>>> def factorial_verbose(number):
...     for i in range(number):
...             yield f'{i + 1} x '
...
>>> res = ''.join([x for x in factorial_verbose(5)])
>>> res = ' '.join([res[:len(res)-3], '=', str(math.factorial(5))])
>>> res
'1 x 2 x 3 x 4 x 5 = 120'

@Nir Levy, ne eğlenceli küçük bir şey
Pedro Rodrigues

1

Bir satır, hızlı ve büyük sayılar da çalışır:

#use python3.6.x for f-string
fact = lambda x: globals()["x"] if exec(f'x=1\nfor i in range(1, {x+1}):\n\tx*=i', globals()) is None else None

0

Bunun cevaplandığını biliyorum, ancak burada, aralığı daha kolay ve daha kompakt hale getiren ters aralıklı bir liste kavrayışı olan başka bir yöntem var:

    #   1. Ensure input number is an integer by attempting to cast value to int
    #       1a. To accomplish, we attempt to cast the input value to int() type and catch the TypeError/ValueError 
    #           if the conversion cannot happen because the value type is incorrect
    #   2. Create a list of all numbers from n to 1 to then be multiplied against each other 
    #       using list comprehension and range loop in reverse order from highest number to smallest.
    #   3. Use reduce to walk the list of integers and multiply each against the next.
    #       3a. Here, reduce will call the registered lambda function for each element in the list.
    #           Reduce will execute lambda for the first 2 elements in the list, then the product is
    #           multiplied by the next element in the list, and so-on, until the list ends.

    try :
        num = int( num )
        return reduce( lambda x, y: x * y, [n for n in range(num, 0, -1)] )

    except ( TypeError, ValueError ) :
        raise InvalidInputException ( "Input must be an integer, greater than 0!" )

Kodun tam sürümünü bu özette görebilirsiniz: https://gist.github.com/sadmicrowave/d4fbefc124eb69027d7a3131526e8c06


1
Kullanımına gerek yok [n for n in range(num, 0, -1)], rangezaten iterable olduğunu.
Mark Mishyn

0

Bunu yapmanın başka bir yolu da np.prodaşağıda gösterilenleri kullanmaktır :

def factorial(n):
    if n == 0:
        return 1
    else:
         return np.prod(np.arange(1,n+1))

0

Çarpınım n ile temsil edilen bir pozitif tam sayı, n, bir !, az tüm pozitif tamsayılar ürünüdür ya da n'ye eşittir.

formül :n! = n * (n-1) * (n-2) * (n-3) * (n-4) * ....... * 1

Yerleşik işlev / kütüphane vb. Kullanarak faktöriyel faktöriyel bulmak için çeşitli yöntemler vardır. Burada faktöriyel temel tanımı referans ile kullanıcı tanımlı fonksiyon oluşturdu.

def factorial(n):
    fact = 1
    for i in range(1,n+1):
        fact = fact * i
    return(fact)

print(factorial(4))

Faktör fonksiyonunu recursiveaşağıda gösterildiği gibi tekniği kullanarak da uygulayabiliriz . Ancak bu yöntem yalnızca küçük tamsayı değerleri için etkilidir. Çünkü özyinelemede, işlev tekrar tekrar çağrılır ve yığının korunması için bir faktörün bulunması için büyük tamsayı değerleri için etkili veya optimize edilmiş bir yaklaşım olmayan bir bellek alanı gerektirir.

def factorial(n):
    if n == 1:
        return 1
    else:
        return n * factorial(n-1)

print(factorial(4))


0

Aşağıdaki kodda, faktöriyel hesaplamak istiyorum numarasının girdisini alıyorum, Bundan sonra faktöriyel 1,2, ...., (sayı faktöriyelinden başlayan sayılarla hesaplamak istediğimiz -> sayısını çarpıyorum -1'i hesaplamak istiyorum)

    f = int(input("Enter a number whose factorial you want to calculate = "))#Number 
                                           #whose factorial I want to calculate                              
for i in range(1,f): #assume I have taken f as 5
    f=f*i # In 1st iteration f=5*1 => 5 , in second iteration f = 5*2 => 10, 3rd 
          #iteration f = 10*3 =>30, 4th iteration f = 30*4 =>120  
print(f) #It will print the updated value of "f" i.e 120
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.