isPrime works but UnBoundLocalError when mapping on list

Andreas Tawn andreas.tawn at ubisoft.com
Tue Jul 15 13:28:09 EDT 2008


>defn noob 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]
>> --
>> http://mail.python.org/mailman/listinfo/python-list
>> 
>
>========================================
>Yep - "local variable 'x' referenced before assignment" is correct.
>You state: for x in range... but x doesn't exist until initialized.
>   To save a loop, initialize x=2 (the minimum value) and loop executes
>   on pass one.
>In a straight 'C' program
>   (  for (x=1, x=(nbr+1), x++)  etc...  )
>   the x is initialized and forceably incremented.
>   seems Python does not auto initialize but does auto increment.

I think a better explanation is that in your original function, x only
existed while the for loop was running. As soon as execution hit the
break statement, x ceased to exist. When you attempted to reference it
in the next line, Python has no variable called x so it complains that x
hasn't been initialised.

A more idiomatic way to write it...

def isPrime(nbr):
    if nbr <= 1:
        return False
    for x in xrange(2, nbr+1):
        if not nbr % x:
            return x == nbr

Cheers,

Drea



More information about the Python-list mailing list