1

I stumbled upon another basic concept I've missed in Python:

Having this basic for (foreach) loop:

x = 15
for x in range(10):
    continue
print(x)

The value for x I expected was 15, but instead I got 9.

The same code snippet in C returns x's original value – 15:

#include <stdio.h>

int main(void) 
{
  int x = 15;
  for (int x = 0; x < 10; x++)
  {
    continue;
  }
  printf("%d", x);
  return 0;
}

I can't figure out how the variable scope works here.

Since x is declared outside the for loop scope, shouldn't a new local variable be created during the lifetime of the loop?

Why is x being overridden in the Python version then?

mkrieger1
  • 19,194
  • 5
  • 54
  • 65
  • I don't know about c, but in python, any variable will always take the value it's assigned – Nathan Nov 17 '18 at 23:29
  • try adding a print statement `print(x)` before continue to see what happens. – Nathan Nov 17 '18 at 23:29
  • @Nathan adding the print statement would print each value of x, from 0 to 9, but I can't understand why does it override x instead of creating a new local variable, like for example C does. – Kamen Hristov Nov 17 '18 at 23:32
  • 3
    A `for` loop doen't create a new scope in Python. For scoping rules, see for example https://stackoverflow.com/questions/291978/short-description-of-the-scoping-rules – Thierry Lathuille Nov 17 '18 at 23:33
  • @ThierryLathuille Thanks! Great post, I should've found it earlier! – Kamen Hristov Nov 17 '18 at 23:40

1 Answers1

3

This is not the same. In C, you explicitly create a new variable, whereas in Python, you reuse the name in the for scope, ending up overriding the previous value.

So the C equivalent really is:

#include <stdio.h>

int main(void) 
{
  int x = 15;
  for (x = 0; x < 10; ++x)
  {
    continue;
  }
  --x; // To accommodate the different behavior of the range loop
  printf("%d", x);
  return 0;
}

Don't forget that in Python, variables are just entries in a dictionary, dynamically created, whereas in C, they are independent, static items.

Matthieu Brucher
  • 21,634
  • 7
  • 38
  • 62