unintuitive for-loop behavior
Jussi Piitulainen
jussi.piitulainen at helsinki.fi
Sat Oct 1 10:28:11 EDT 2016
I'm not sure any more to what message this should be a followup, but
here is a demonstration of two different semantics of the for-loop
variable scope/update, this time with nested loops using the same loop
variable name. The first function, tabulate, uses Python semantics ("t"
for true, if you like); the second, fabulate, is a translation ("f" for
false, if you like) that uses the magical semantics where the loop
variable is not only local to the loop but also a different variable on
each iteration. The latter property makes no difference in this
demonstration, but the former does; there's also a spurious counter that
is not local to the nested loops, just to be sure that it works as
expected (it does).
A summary of sorts: it's possible to demonstrate the scope difference in
Python code, with no box in sight; boxes are irrelevant; the relevant
issue is what function and when the loop variable is associated with,
explicitly or implicitly.
def tabulate(m, n):
for i in range(m):
print(i, end = ': ')
c = 0
for i in range(n):
print(i, end = ', ' if i + 1 < n else ' : ')
c += 1
print(i, c)
def fabulate(m, n):
c = None # because c belong in this scope
g1 = iter(range(m))
try:
while True:
def g2(i):
nonlocal c
print(i, end = ': ')
c = 0
g3 = iter(range(n))
try:
while True:
def g4(i):
nonlocal c
print(i, end = ', ' if i + 1 < n else ' : ')
c += 1
g4(next(g3))
except StopIteration:
pass
print(i, c)
g2(next(g1))
except StopIteration:
pass
print('Python:')
tabulate(3, 4)
print()
print('Magick:')
fabulate(3, 4)
# Output from the above, each line being
# outer i: each inner i : i after inner loop, c
# where either c correctly counts inner steps but
# Python inner i clobbers outer i, Magick not.
#
# Python:
# 0: 0, 1, 2, 3 : 3 4
# 1: 0, 1, 2, 3 : 3 4
# 2: 0, 1, 2, 3 : 3 4
#
# Magick:
# 0: 0, 1, 2, 3 : 0 4
# 1: 0, 1, 2, 3 : 1 4
# 2: 0, 1, 2, 3 : 2 4
More information about the Python-list
mailing list