Python programs / Numbers / Perfect number check

Python Program to Check a Perfect Number

Beginner Numbers

Checks whether a number equals the sum of its proper divisors, the smaller numbers that divide it exactly, as 28 does.

A perfect number equals the sum of its proper divisors: the smaller numbers that divide it exactly. 28 is one: its proper divisors are 1, 2, 4, 7 and 14, and 1 + 2 + 4 + 7 + 14 = 28. Perfect numbers are rare: below 10,000 there are only four, 6, 28, 496 and 8128.

Program

def is_perfect(number):
    """True if number is a perfect number."""
    total = 0
    for divisor in range(1, number):
        if number % divisor == 0:
            total += divisor
    return total == number


print("28:", is_perfect(28))
print("12:", is_perfect(12))

Open in the editor Download perfect_number.py

Output

28: True
12: False

How it works

  1. total holds the sum of the divisors found so far. It starts at 0.
  2. The loop tries every number from 1 up to one less than number. range() stops before its end, so the number itself, which always divides it, isn't counted.
  3. % gives the remainder of a division. A remainder of 0 means divisor divides the number exactly, so it's added to the total.
  4. The number is perfect when that total equals the number itself.
  5. The program checks 28, which is perfect, and 12, which isn't: its proper divisors 1, 2, 3, 4 and 6 add up to 16.

Other ways to write it

With a list comprehension

A list comprehension collects the divisors in one line, and sum() adds them up:

def is_perfect(number):
    divisors = [d for d in range(1, number) if number % d == 0]
    return sum(divisors) == number

print(is_perfect(6), is_perfect(8))

Checking divisors in pairs

Divisors come in pairs that multiply to the number: 2 ร— 14 = 28 and 4 ร— 7 = 28. The smaller of each pair is never more than the square root of the number, so the loop can stop there and add both. For 8128 that's 89 tries instead of 8127.

from math import isqrt

def is_perfect(number):
    if number < 2:  # 1 has no proper divisors
        return False
    total = 1  # 1 divides every number
    for divisor in range(2, isqrt(number) + 1):
        if number % divisor == 0:
            partner = number // divisor
            total += divisor
            if partner != divisor:  # 36 = 6 x 6: add 6 once
                total += partner
    return total == number

print(is_perfect(8128), is_perfect(8000))

Try it yourself

  • Check 6 and 496, which are perfect, and 1, which isn't: it has no proper divisors, so their total is 0.
  • Print every perfect number below 1000 with a loop. There are three: 6, 28 and 496.
  • Make the loop go only up to half the number, with range(1, number // 2 + 1). No proper divisor is bigger than half, so the result is the same with half the work.
  • Say whether a number is abundant, with divisors that add up to more than it (12's make 16), or deficient, with divisors that add up to less (8's make 1 + 2 + 4 = 7).

More numbers programs

Share this program