0

I am playing around with recursion and decided to try and write a function that can take in either a single number or a list of numbers and determine if each number is prime or not.

If the function input is a single number, the function should return True if the number is prime, and False if it is not.

If the function input is a list of numbers, the function should return a list of tuples of the form (num, bool) where num is an item from the list and bool says if that number is prime or not.

I have a function that sortof works, but I have run into some very interesting behavior and I was hoping someone could help me understand what is going on. Specifically, if you run the function definition in one cell of a jupyter notebook and in the next cell run the test case, the function will work.

The weird behavior I can't explain is that if I then run the test case a second time without rerunning the function definition, the entire output from the first call has somehow stayed in memory, so the output of running the test case a second time will be the first output and the second output.

This pattern continues if you run the test a 3rd, 4th, 5th time etc.

To reproduce, simply define this function in a jupyter notebook:

def is_prime(num, list_solution=[], recurse=False):
    
    prime = True
    
    if type(num) == list:
        if len(num) > 1:
            recurse = True
            next_numbers = num[1:]
            num = num[0]
        else: 
            num = num[0]
    
    if num <= 1:
        prime = False
    else:
        divisors = list(range(2, (num + 2) // 2))
        
        for divisor in divisors:
            if num % divisor == 0:
                prime = False
                #print("this number isn't prime")
                break
    
    if recurse == True:

        list_solution.append((num, prime))
        print("Intermediate result: ", list_solution, "\n\n")
        
        list_solution = is_prime(num=next_numbers, list_solution=list_solution)
        return list_solution
    
    if list_solution != []:
        return list_solution
    else: 

        return prime

and then in the next cell, run this test case two times:

list_test = list(range(1,101))
print(is_prime(num=list_test))

One other note, if you call the test and explicitly set list_solution=[], like this:

list_test = list(range(1,101))
print(is_prime(num=list_test, list_solution=[]))

The problem disappears, however I don't understand why I would need to do that when list_solution=[] is in the function definition as a default parameter.

Please let me know if you see what I have done wrong, Thank you!!

-Braden

Braden Anderson
  • 141
  • 1
  • 11
  • 1
    Have a look at: https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes – Peter Lang May 29 '21 at 05:54
  • 3
    Welcome to the [least astonishment](https://stackoverflow.com/questions/1132941/least-astonishment-and-the-mutable-default-argument) club :) – hilberts_drinking_problem May 29 '21 at 06:04
  • 2
    [Default Parameters in Python are static](https://stackoverflow.com/questions/1132941/least-astonishment-and-the-mutable-default-argument) This is your problem. basically they carry over from previous time you called the function to next time. – Yoshikage Kira May 29 '21 at 06:05

0 Answers0