Question: Looking for a way to explain something in Python to my students. If we start with number\_list = range(100), we can use a for loop such as...

```
for n in number_list: (do something)  

```

If we have the same set up, but try to use a while loop, n comes back as undefined. How do I explain that?

```
while n in number_list < 20: (do something)  --> n is undefined

```

I guess it is more curious why it's OK in the for loop. I have been harping on them to initialize variables before using them, so why does n work just fine in the for loop?

Answer: 
The `in` in a `for` loop has a different connotation from the `in` used in a `while` loop.

The `for` loop's syntax is defined in the [grammar file](https://docs.python.org/3/reference/grammar.html#full-grammar-specification) for the language, particularly, this line:

```
for_stmt: 'for' exprlist 'in' testlist ':' suite ['else' ':' suite]

```

Which indicates that `in` is part of the *syntax* that defines a `for` loop.

In the case of a `while` loop, which is a *condition controlled* loop. Anything that comes after `while` is treated as an expression that is to be evaluated and its truthiness tested.

So, the `<something>` in `while <something>:` is an expression. In your case, it is `n in number_list < 20`. In this case, the `in` has a different connotation, it is an *operator* that is used to test inclusion.

```
In [173]: n = 4

In [174]: n in range(1, 10)
Out[174]: True

```

In your particular case, `n` is not defined at the time the expression is evaluated, and so a `NameError` is raised.

---

I understand that this might be too complicated an answer to throw at students who have next to no experience with python.

I would touch upon the fact that the `in` in `for ... in ...` is an artefact of the syntax for a `for` loop, and the `in` in the `while <something>` statement is an operator, and go from there.
Your current `while` loop is mostly gibberish. There's no `in` clause in a `while` statement (unless you're using the `in` operator to check if a value is a member of a container). Unlike a for loop, a `while` doesn't assign any value to a name on each iteration, it just checks the truth value of the expression you give it. That expression needs to be valid *before* the loop runs!

You can write a `while` loop that is almost equivalent to your `for` loop:

```
number_list = range(100)

iterator = iter(number_list)
try:
    while True:
        n = next(iterator)

        # do stuff here with n (body of the loop)

except StopIteration:
    pass

```

(The only way this is different from the for loop is that it creates the name `iterator` in the current namespace, while a `for` loop stores its iterator internally, without it being accessible to Python code.)

Unfortunately, that loop is unlikely to be easier for your students to understand, since exceptions are probably more complicated than looping.

If you only need to be able to iterate over a sequence (such as a `list` or a `range`), you can make a simpler `while` loop that uses an index to get each value from the sequence, rather than using the iterator protocol:

```
number_list = range(100)

i = 0
while i < len(number_list):
    n = number_list[i]

    # do stuff with n here

```