1

I've run into a strange case in my Python code, and I'm trying to figure out why this occurs.

rounds = 10
probability = 100
items = [1, 2, 3, 4, 5]
from numpy.random import uniform
for r in range(1, rounds):
    sample = {item: uniform() < probability for item in items}

When I run the above code, I get the following NameError:

File "sample.py", line 6, in <module>
  sample = {item: uniform() < probability for item in items}
File "sample.py", line 6, in <dictcomp>
  sample = {item: uniform() < probability for item in items}
NameError: name 'uniform' is not defined

This is very strange, since I am importing uniform directly before using it in the following line. I got the same error using the random module. I'm using other packages in my code (including argparse and pickle) but only the random number generation is giving me errors. I'm running Python 3 on a Windows machine. I also get the same error when I move the import statement inside the for loop.

rounds = 10
probability = 100
items = [1, 2, 3, 4, 5]
for r in range(1, rounds):
    from numpy.random import uniform
    sample = {item: uniform() < probability for item in items}

What could be causing this error?

EDIT: I encountered another interesting phenomenon. The below code blocks are giving the same NameError for uniform.

from numpy.random import uniform
sample = {item: uniform() for item in [1,2,3]}

... and ...

from numpy.random import uniform
sample = [uniform() for item in [1,2,3]]

However, the following code does NOT give a NameError for uniform.

from numpy.random import uniform
sample = {1: uniform(), 2: uniform(), 3: uniform()}

There seems to be something in the way Python handles dictionary/list comprehensions that makes the first two code blocks illegal but the third one okay.

Shuklaswag
  • 1,003
  • 1
  • 10
  • 27
  • 2
    [mcve], please. Is this inside a class statement? There's clearly some context you're not showing us; your error message didn't come from the exact code you posted. – user2357112 Mar 29 '18 at 23:22
  • @user2357112 thanks, I'll post the minimal complete code to reproduce this error – Shuklaswag Mar 29 '18 at 23:28
  • That's strange. This kind of thing usually only happens with [class statements](https://stackoverflow.com/questions/13905741/accessing-class-variables-from-a-list-comprehension-in-the-class-definition), `exec`, and other constructs that create a scope that can't be used for closure variables. – user2357112 Mar 29 '18 at 23:33
  • Does running the posted code in isolation produce the error, or does it only happen as part of some larger program? – user2357112 Mar 29 '18 at 23:35
  • If you instead do import numpy, and then call the function using numpy.random.uniform() do you get the same error? – enumaris Mar 29 '18 at 23:39
  • @user2357112 This code alone will produce this error. I'm running it as a `.py` script from the terminal. – Shuklaswag Mar 29 '18 at 23:43
  • @enumaris Yep, I get `NameError: name 'numpy' is not defined` – Shuklaswag Mar 29 '18 at 23:43
  • What happens if you try to call `uniform()` outside of a comprehension? If your file is nothing but `from numpy.random import uniform; uniform()`, do you get an error? – user2357112 Mar 29 '18 at 23:45
  • @user2357112, nope, there's no error – Shuklaswag Mar 30 '18 at 00:20
  • I edited the question. The for-loop is unnecessary. Furthermore, it looks like the error has to do with calling numpy's `uniform()` function inside of a list/dict-comprehension. – Shuklaswag Mar 30 '18 at 00:29
  • What happens if you put parentheses around `uniform() < probability` in your comprehension? – pjs Mar 30 '18 at 00:30
  • I gotta say, I'm having no luck reproducing your error with Python 3.6.4 on a Mac. – pjs Mar 30 '18 at 00:41
  • What are you using to execute Python? If you're running the script as `python sample.py`, what does `which python` produce? Something is really weird about how you're executing this code. – user2357112 Mar 30 '18 at 01:07
  • yep, I'm running it like `python sample.py` from a terminal. I'm running Windows, so `where.exe python` returns `C:\Python35\python.exe`. Interestingly, the failing code *does* work when I run Python interactively. – Shuklaswag Mar 30 '18 at 01:10
  • There's definitely something weird with my version of Python. Inside of another dict comprehension, I tried to access a variable `r` that I declared outside of the dictionary, and Python returned another `NameError` for `r`. At least for now, I'm going to step around this by using a simple `for` loop instead of comprehensions. – Shuklaswag Mar 30 '18 at 01:19
  • 2
    If this is Windows, I suggest uninstalling and reinstalling Python and seeing if the problem goes away. (Try Python 3.6.) Digging into the root cause could be interesting, but it's probably not the best use of your time. – user2357112 Mar 30 '18 at 02:42

0 Answers0