Fungsi Faktorial dengan Python

140

Bagaimana cara saya menghitung faktorial dari bilangan bulat dengan Python?

Nir Levy
sumber

Jawaban:

195

Cara termudah adalah dengan menggunakan math.factorial(tersedia di Python 2.6 dan yang lebih baru):

import math
math.factorial(1000)

Jika Anda ingin / harus menulisnya sendiri, Anda dapat menggunakan pendekatan berulang:

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

atau pendekatan rekursif :

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

Perhatikan bahwa fungsi faktorial hanya ditentukan untuk bilangan bulat positif jadi Anda juga harus memeriksa itu n >= 0dan itu isinstance(n, int). Jika tidak, naikkan a ValueErroratau a TypeErrormasing - masing. math.factorialakan mengurus ini untukmu.

schnaader
sumber
2
Saya tidak mengerti bagaimana Anda dapat menggunakan factorialdalam factorialfungsi tersebut. Bagaimana Anda bisa menggunakan fungsi yang sama dalam fungsi yang saat ini Anda definisikan? Saya baru mengenal Python jadi saya hanya mencoba untuk mengerti.
J82
8
@ J82: Konsep yang digunakan di sini disebut rekursi ( en.wikipedia.org/wiki/Recursion_(computer_science) ) - fungsi yang memanggil dirinya sendiri baik-baik saja dan sering kali berguna.
schnaader
Fungsi rekursif akan menaikkan a RecursionErroruntuk bilangan apa pun yang lebih besar dari 998 (coba factorial(999)) kecuali Anda meningkatkan batas rekursi Python
Boris
114

Pada Python 2.6 dan yang lebih baru, coba:

import math
math.factorial(n)
Joril
sumber
Dimulai dengan Python 3.9 , meneruskan a floatke fungsi ini akan memunculkan a DeprecationWarning. Jika Anda ingin melakukan itu, Anda perlu mengonversi nmenjadi intsecara eksplisit:, math.factorial(int(n))yang akan membuang apa pun setelah desimal, jadi Anda mungkin ingin memeriksanyan.is_integer()
Boris
18

Solusi yang ada

Solusi terpendek dan mungkin tercepat adalah:

from math import factorial
print factorial(1000)

Bangun sendiri

Anda juga dapat membuat solusi Anda sendiri. Umumnya Anda memiliki dua pendekatan. Salah satu yang paling cocok untuk saya adalah:

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

print factorial(1000)

(ini juga berlaku untuk angka yang lebih besar, jika hasilnya menjadi long)

Cara kedua untuk mencapai hal yang sama adalah:

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

print factorial(1000)
Tadeck
sumber
7
def factorial(n):
    if n < 2:
        return 1
    return n * factorial(n - 1)
Nishanth
sumber
1
factorial(999)(dan di atasnya) akan menaikkan nilai a RuntimeErrorkecuali Anda meningkatkan batas rekursi Python
Boris
5

Jika Anda menggunakan Python2.5 atau lebih lama, coba

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

untuk Python yang lebih baru, ada faktorial dalam modul matematika seperti yang diberikan dalam jawaban lain di sini

John La Rooy
sumber
1
Ini adalah jawaban Python 2-satunya, reducetelah dihapus dari Python 3.
Boris
@ Boris, dengan Python3 Anda hanya perlu menambahkanfrom functools import reduce
John La Rooy
Ini telah dihapus karena suatu alasan, Anda tidak boleh menggunakannya 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
Yordania
sumber
3

Untuk alasan kinerja, jangan gunakan rekursi. Ini akan menjadi bencana.

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

Periksa hasil yang sedang berjalan

cProfile.run('fact(126000)')

4 function calls in 5.164 seconds

Menggunakan stack memang nyaman (seperti panggilan rekursif), tetapi ada biaya yang harus dikeluarkan: menyimpan informasi mendetail dapat menghabiskan banyak memori.

Jika stack tinggi, artinya komputer menyimpan banyak informasi tentang pemanggilan fungsi.

Metode ini hanya membutuhkan memori konstan (seperti iterasi).

Atau Menggunakan for loop

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

Periksa hasil yang sedang berjalan

cProfile.run('fact(126000)')

4 function calls in 4.708 seconds

Atau Menggunakan matematika fungsi builtin

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

Periksa hasil yang sedang berjalan

cProfile.run('fact(126000)')

5 function calls in 0.272 seconds
binbjz.dll
sumber
1
Saya pikir ini while loop terlihat sedikit lebih bersih <! - language: python -> def fact (n): ret = 1 while n> 1: n, ret = n - 1, ret * n return ret
edilio
0

Cara lain untuk melakukannya adalah dengan menggunakan yang np.prodditunjukkan di bawah ini:

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