isPrime works but UnBoundLocalError when mapping on list
Mensanator
mensanator at aol.com
Tue Jul 15 13:42:03 EDT 2008
On Jul 15, 12:28 pm, "Andreas Tawn" <andreas.t... at ubisoft.com> wrote:
> >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.
The for loop never ran.
> As soon as execution hit the break statement,
It never hit the break statement, the first call from
[isPrime(y) for y in range(11)]
attempted to do for x in range(2,1).
> x ceased to exist.
Something has to exist before it can cease 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.
Right conlusion but false premise.
>
> 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