467,219 Members | 1,452 Online

# isPrime works but UnBoundLocalError when mapping on list

 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 "", line 1, in [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 "", line 1, in 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
• viewed: 1417
Share:
8 Replies
 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 "", line 1, in [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 "", line 1, in 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
 >defn noob wrote: >isPrime works when just calling a nbr but not when iterating on alist, why? adding x=1 makes it work though but why do I have to addit?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 "", line 1, in [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 "", line 1, in 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
 On Jul 15, 11:26*am, defn noob [isPrime(y) for y in range(11)] Traceback (most recent call last): * File "", line 1, in * * [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 "", line 1, in * * 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
 On Jul 15, 7:28*pm, Mensanator >[isPrime(y) for y in range(11)] Traceback (most recent call last): * File "", line 1, in * * [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 "", line 1, in * * 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
 On Jul 15, 12:28*pm, "Andreas Tawn" >>[isPrime(y) for y in range(11)] Traceback (most recent call last): * File "", line 1, in * * [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 "", line 1, in * * map(isPrime, range(100)) * File "C:\Python25\Progs\blandat\myMath.py", line 9, in isPrime * * if x == nbr: UnboundLocalError: local variable 'x' referenced before assignmentisPrime(10) FalseisPrime(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
 On Jul 15, 12:36*pm, defn noob [isPrime(y) for y in range(11)] Traceback (most recent call last): * File "", line 1, in * * [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 "", line 1, in * * 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
 Mensanator wrote: On Jul 15, 12:36 pm, defn noob On Jul 15, 7:28 pm, Mensanator >On Jul 15, 11:26 am, defn noob >[isPrime(y) for y in range(11)]Traceback (most recent call last): File "", line 1, in [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 "", line 1, in 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)Trueadding 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 youinstead test that nbr+1 is greater than 2? Or call it withrange(3,11) instead of range(11)? x isn't initializedbecause if nbr+1 is <=2, the for loop has an invalid rangeand 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 Falsethis works for all primes, if i want to not include 1 i just do ifnbr<=1 return falseyou 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
 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.

### Similar topics

 3 posts views Thread by Brad Clements | last post: by 6 posts views Thread by Alex Gittens | last post: by 8 posts views Thread by David Bear | last post: by 15 posts views Thread by Paddy | last post: by 9 posts views Thread by Camellia | last post: by reply views Thread by henk-jan ebbers | last post: by 2 posts views Thread by Konstantinos Pachopoulos | last post: by reply views Thread by Andreas Tawn | last post: by reply views Thread by Fredrik Lundh | last post: by reply views Thread by SwissProgrammer | last post: by 1 post views Thread by SwissProgrammer | last post: by reply views Thread by isladogs | last post: by 2 posts views Thread by joaofigu | last post: by 1 post views Thread by Divyan | last post: by 8 posts views Thread by SueHopson | last post: by 2 posts views Thread by irsmalik | last post: by 1 post views Thread by jobsrod | last post: by 1 post views Thread by MitchR | last post: by