isPrime works but UnBoundLocalError when mapping on list

norseman norseman at hughes.net
Tue Jul 15 14:48:00 EDT 2008


Mensanator wrote:
> On Jul 15, 12:36 pm, defn noob <circularf... at yahoo.se> wrote:
>> On Jul 15, 7:28 pm, Mensanator <mensana... at aol.com> wrote:
>>
>>
>>
>>
>>
>>> On Jul 15, 11:26 am, defn noob <circularf... at yahoo.se> wrote:
>>>> isPrime works when just calling a nbr but not when iterating on a
>>>> list, why? adding x=1 makes it work though but why do I have to add
>>>> it?
>>>> Is there a cleaner way to do it?
>>>> def isPrime(nbr):
>>>>     for x in range(2, nbr + 1):
>>>>         if nbr % x == 0:
>>>>             break
>>>>     if x == nbr:
>>>>         return True
>>>>     else:
>>>>         return False
>>>>>>> [isPrime(y) for y in range(11)]
>>>> Traceback (most recent call last):
>>>>   File "<pyshell#45>", line 1, in <module>
>>>>     [isPrime(y) for y in range(11)]
>>>>   File "C:\Python25\Progs\blandat\myMath.py", line 9, in isPrime
>>>>     if x == nbr:
>>>> UnboundLocalError: local variable 'x' referenced before assignment
>>>>>>> map(isPrime, range(100))
>>>> Traceback (most recent call last):
>>>>   File "<pyshell#38>", line 1, in <module>
>>>>     map(isPrime, range(100))
>>>>   File "C:\Python25\Progs\blandat\myMath.py", line 9, in isPrime
>>>>     if x == nbr:
>>>> UnboundLocalError: local variable 'x' referenced before assignment>>> isPrime(10)
>>>> False
>>>>>>> isPrime(11)
>>>> True
>>>> adding x=1 makes it work though:
>>>> def isPrime(nbr):
>>>>     x=1
>>>>     for x in range(2, nbr + 1):
>>>>         if nbr % x == 0:
>>>>             break
>>>>     if x == nbr:
>>>>         return True
>>>>     else:
>>>>         return False
>>>>>>> [isPrime(y) for y in range(11)]
>>>> [False, True, True, True, False, True, False, True, False, False,
>>>> False]
>>> No, it doesn't. You are falsely reporting that 1 is prime.
>>> And instead of making the fake variable x, shouldn't you
>>> instead test that nbr+1 is greater than 2? Or call it with
>>> range(3,11) instead of range(11)? x isn't initialized
>>> because if nbr+1 is <=2, the for loop has an invalid range
>>> and doesn't even execute.
>> def isPrime(nbr):
>>     for x in range(2, nbr + 1):
>>         if nbr % x == 0:
>>             break
>>     if x == nbr:
>>         return True
>>     else:
>>         return False
>>
>> this works for all primes, if i want to not include 1 i just do if
>> nbr<=1 return false
>>
>> you are answering the wrong question.
> 
> No, I also mentioned the for loop having an invalid range,
> which is why your original failed.
> 
> Pointing out that 1 isn't prime was a bonus.
> 
>> anyway here is a clear one:
>> def isPrime(nbr):
>>     if nbr < 2:
>>         return False
>>     for x in range(2, nbr + 1):
>>         if nbr % x == 0:
>>             return nbr == x
> 
> I suppose you're not interested in knowing you don't
> have to test anything higher than the square root of
> the number.
> 
> --
> http://mail.python.org/mailman/listinfo/python-list
> 
===========================
"don't...test...higher than the square root..."

I wondered when that was going to show up.
I too had a good math teacher.

Steve
norseman at hughes.net



More information about the Python-list mailing list