By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,423 Members | 1,294 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,423 IT Pros & Developers. It's quick & easy.

isPrime works but UnBoundLocalError when mapping on list

P: n/a
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]
Jul 15 '08 #1
Share this Question
Share on Google+
8 Replies


P: n/a

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.
Steve
no******@hughes.net
Jul 15 '08 #2

P: n/a
>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
Jul 15 '08 #3

P: n/a
On Jul 15, 11:26*am, defn noob <circularf...@yahoo.sewrote:
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.
Jul 15 '08 #4

P: n/a
On Jul 15, 7:28*pm, Mensanator <mensana...@aol.comwrote:
On Jul 15, 11:26*am, defn noob <circularf...@yahoo.sewrote:
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.
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
Jul 15 '08 #5

P: n/a
On Jul 15, 12:28*pm, "Andreas Tawn" <andreas.t...@ubisoft.comwrote:
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
Jul 15 '08 #6

P: n/a
On Jul 15, 12:36*pm, defn noob <circularf...@yahoo.sewrote:
On Jul 15, 7:28*pm, Mensanator <mensana...@aol.comwrote:


On Jul 15, 11:26*am, defn noob <circularf...@yahoo.sewrote:
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.

Jul 15 '08 #7

P: n/a

Mensanator wrote:
On Jul 15, 12:36 pm, defn noob <circularf...@yahoo.sewrote:
>On Jul 15, 7:28 pm, Mensanator <mensana...@aol.comwrote:


>>On Jul 15, 11:26 am, defn noob <circularf...@yahoo.sewrote:
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
no******@hughes.net
Jul 15 '08 #8

P: n/a


Andreas Tawn wrote:
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.
Wrong. For loop variables continue after the loop exits. This is
intentional. Mensanator gave the correct explanation (loop never enters
for nbr==1).

Jul 15 '08 #9

This discussion thread is closed

Replies have been disabled for this discussion.