2

I'm kind of new to programming. I'm trying to write an algorithm in python that gives all the prime factors of a number:

factors=[]
def factor(n):
    for i in range(2,n+1):
        if n%i==0:
            factors.append(i)
            factor(int(n/i))
            break
    return factors

It works, but whenever I run the 'factor' function again, it just appends to the already populated 'factors' list - how can I get the list to clear each time the function 'factor' is run?

braX
  • 11,506
  • 5
  • 20
  • 33
  • too bad this is marked as answered by the "Clearing Python lists" link above. Some is marking duplicates based on title without reading the questions. This is clearly a different question... IMHO – Phil Cooper Mar 06 '14 at 23:24

2 Answers2

6

Declare a local variable inside the function. In your code you're actually modifying the global variable factors every time you call factor().

def factor(n, factors=None):
    factors = [] if factors is None else factors 
    for i in range(2, n + 1):
        if n%i==0 and i not in factors: #checks for duplicates as well
            factors.append(i)
            factor(int(n / i),factors) #pass the factors list in the recurive call
            break
    return factors

factor(20) #returns [2, 5]
Ashwini Chaudhary
  • 244,495
  • 58
  • 464
  • 504
  • Thanks - I went this was my final result: def factor(n,factors=None): factors=[] if factors is None else factors for i in range(2,n+1): if n%i==0: factors.append(i) factor(int(n/i),factors) break return factors as I want all prime factors, including duplicates - but thanks for your help! – user2396812 May 19 '13 at 20:32
  • What if in case of recursion?. – Suryaprakash Pisay Sep 01 '18 at 12:36
0

@ashwini-chaudhary has a great answer and the it it the most common idiom I use for this. The OP was asking a generalized question so I will offer an amended solution which makes use of a python closure to do the same.

It is two lines longer (one to declare an inner function and one to call it) and might "uglier" to some but it has the advantage of not adding argments to the orignial function that the caller should not see or use and not calling the contitional assignment at each recursion.

def factor2(n):
    factors = []
    def fact(n):
        for i in range(2, n + 1):
            if n%i==0 and i not in factors: #checks for duplicates as well
                factors.append(i)
                factor(int(n / i),factors) #pass the factors list in the recurive call
                break
    fact(n)
    return factors
Phil Cooper
  • 5,747
  • 1
  • 25
  • 41