unintuitive for-loop behavior

Steve D'Aprano steve+python at pearwood.info
Sun Oct 2 00:21:35 EDT 2016


On Sun, 2 Oct 2016 12:28 am, Jussi Piitulainen wrote:

> 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. 

I'm sorry, I don't understand what you mean by "Python semantics" versus "a
translation". A translation of what? In what way is it "magical semantics"?
I see nothing magical in your code: it is Python code.

Of course, it is complex, complicated, convoluted, obfuscated, hard to
understand, non-idiomatic Python code, but there's nothing magical in it
(unless you count nonlocal as magic). And it does nothing that can't be
done more simply: just change the tabulate inner loop variable to a
different name.


def fabulate2(m, n):
    # The simple, Pythonic, non-complicated way.
    for i in range(m):
        print(i, end = ': ')
        c = 0
        for j in range(n):
            print(j, end = ', ' if j + 1 < n else ' : ')
            c += 1
        print(i, c)


Your version of tabulate and fabulate:
py> tabulate(3, 4)
0: 0, 1, 2, 3 : 3 4
1: 0, 1, 2, 3 : 3 4
2: 0, 1, 2, 3 : 3 4

py> fabulate(3, 4)
0: 0, 1, 2, 3 : 0 4
1: 0, 1, 2, 3 : 1 4
2: 0, 1, 2, 3 : 2 4

My simple version of fabulate:

py> fabulate2(3, 4)
0: 0, 1, 2, 3 : 0 4
1: 0, 1, 2, 3 : 1 4
2: 0, 1, 2, 3 : 2 4


> 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.

I don't know what "scope difference" you think you are demonstrating.
tabulate() has a single scope, fabulate() has multiple scopes because it
has inner functions that take i as argument, making them local to the inner
functions. Um, yeah, of course they are different. They're different
because you've written them differently. What's your point?

As far as I can see, all you have demonstrated is that it is possible to
write obfuscated code in Python. But we already knew that.




-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.




More information about the Python-list mailing list