isPrime works but UnBoundLocalError when mapping on list

Mensanator mensanator at aol.com
Tue Jul 15 14:30:14 EDT 2008


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.




More information about the Python-list mailing list