I’ve created a function that takes a number and, if it’s prime, tells you so, or if it’s composite, gives you the prime factors of the number (and if it’s 1, tells you that it’s neither).
Theoretically it should work for an infinitely large number, but at 8 digits it starts to slow down significantly, particularly if the prime factors are large. I’m fairly new at Python, so I’d welcome any feedback, especially on how to make it faster.
I’m aware that there are things I could have done more efficiently from the start — some of which I’ve become aware from looking at other Python questions in this same vein on this site — but while I would find advice like ‘this bit’s ill-conceived, rip it out and write something else entirely’ helpful, I’d prefer best-practices things, and ways to make it faster without totally changing the premises (as it were).
I haven’t annotated it because (as far as I’m aware), it’s fairly basic; any old hack could write this, but obviously I can annotate if you’d like.
Here’s the code (in Python 2):
import math def prime_factors(y): n = y def is_prime(x): count = 0 if x > 1: for i in range(2, x): if x % i != 0: count += 1 else: return False break else: return True if count != 0: return True if x == 2: return True def make_p_lst(x): z =  for i in range(2, x): if is_prime(i) == True: z.append(i) return z c = 0 c = int(math.sqrt(y) + 1) prime_lst =  prime_lst = make_p_lst(c) p = is_prime(y) if p == True and y != 1: print '%s is prime.' % (y) return 'Thus, its\' only factors are 1 and itself.' elif y != 1: print '%s is composite, here are its\' prime factors: ' % (y) factors_lst =  while is_prime(y) != True: for i in prime_lst: if y % i == 0: y = y/i factors_lst.append(i) factors_lst.append(y) factors_lst.sort() if factors_lst == 1: factors_lst.remove(1) n = factors_lst return n else: return '1 is neither prime nor composite.' print prime_factors(871)