Velocity Reviews > Unexpected result.

# Unexpected result.

Grzegorz Dostatni
Guest
Posts: n/a

 09-23-2004

Consider the following fragment:

>>> for i in ('a','b','c'):

.... for i in (1,2,3):
.... print i,
.... print i,
....
1 2 3 3 1 2 3 3 1 2 3 3

Now. I believe I know what is happening. The i in both loops refers to the
same variable. My question is whether it would make more sense (be more
intuitive) to have a for loop create its own local scope. (ie. an output
string of
1 2 3 a 1 2 3 b 1 2 3 c

)

Grzegorz

"Some cause happiness wherever they go; others, whenever they go."
- Oscar Wilde (1854-1900)

Larry Bates
Guest
Posts: n/a

 09-23-2004
Actually the result is exactly as expected.
Programming 101 teaches us not to reuse
loop variables in nested loops.

and

People have enough problems with "scope"
already (just monitor this newsgroup for
a while if you don't believe me). Also
consider a variation of your example:

d={}
for i in ('a','b','c'):
for j in (1,2,3):
d[i]=j

If 'j' loop had local scope how could
it reference 'i'?

Larry Bates

"Grzegorz Dostatni" <(E-Mail Removed)> wrote in message
news(E-Mail Removed)...
>
> Consider the following fragment:
>
>>>> for i in ('a','b','c'):

> ... for i in (1,2,3):
> ... print i,
> ... print i,
> ...
> 1 2 3 3 1 2 3 3 1 2 3 3
>
> Now. I believe I know what is happening. The i in both loops refers to the
> same variable. My question is whether it would make more sense (be more
> intuitive) to have a for loop create its own local scope. (ie. an output
> string of
> 1 2 3 a 1 2 3 b 1 2 3 c
>
> )
>
> Grzegorz
>
>
> "Some cause happiness wherever they go; others, whenever they go."
> - Oscar Wilde (1854-1900)
>
>

Steven Bethard
Guest
Posts: n/a

 09-23-2004
Grzegorz Dostatni <grzegorz <at> ee.ualberta.ca> writes:
> My question is whether it would make more sense (be more
> intuitive) to have a for loop create its own local scope

I highly doubt you're going to convince Python to change on this, but you can
always try...

Anyway, there are times when you want to access the loop variable afterwards,
e.g.:

for i, line in enumerate(file(...)):
# do something with each line of the file
print 'lines in file:', i

So the tradeoff is between catching errors like yours (and as Larry Bates
says, you really shouldn't use the same variable in nested loops anyway) and
being able to be more expressive. My suspicion is that there really aren't
too many use cases where you really need to have the same loop variable name
in a nested for loop, but I bet there are a fair number of good use cases for
having access to the loop variable after the end of the loop.

Steve

Paul Rubin
Guest
Posts: n/a

 09-23-2004
"Larry Bates" <(E-Mail Removed)> writes:
> Actually the result is exactly as expected. Programming 101 teaches
> us not to reuse loop variables in nested loops.

Programming 101 usually doesn't say whether a nested loop introduces a
new scope or not. If there's a new scope, it's not re-use of a variable.

Andrew Dalke
Guest
Posts: n/a

 09-23-2004
Grzegorz Dostatni wrote:
> My question is whether it would make more sense (be more
> intuitive) to have a for loop create its own local scope. (ie. an output
> string of
> 1 2 3 a 1 2 3 b 1 2 3 c

If for loops created a new local scope then the following
would not work

for i in range(10):
if data[i] == "stop":
break
else:
return None
print "Found at position", i
.. continue to work with that position ..

In Python only functions, modules, and classes
create a new scope (at least syntax-wise)

If you really, really want a scope there you
can do this

>>> for i in range(5):

.... class Spam:
.... for i in "ABC":
.... print i,
.... print "At end -->", i
.... del i
.... print "After del -->", i
.... i = "qwerty" # show that 'i' gets removed
.... print "After end of class scope", i
....
A B C At end --> C
After del --> 0
After end of class scope 0
A B C At end --> C
After del --> 1
After end of class scope 1
A B C At end --> C
After del --> 2
After end of class scope 2
A B C At end --> C
After del --> 3
After end of class scope 3
A B C At end --> C
After del --> 4
After end of class scope 4
>>>

Strange, but it works. I don't think I've seen
anyone use this in real code, and I don't really

Andrew
http://www.velocityreviews.com/forums/(E-Mail Removed)

Steven Bethard
Guest
Posts: n/a

 09-23-2004
Andrew Dalke <adalke <at> mindspring.com> writes:
> >>> for i in range(5):

> ... class Spam:
> ... for i in "ABC":
> ... print i,

Wow, that's an awesome abuse of classes. How cool! =)

Steve

Bengt Richter
Guest
Posts: n/a

 09-23-2004
On Thu, 23 Sep 2004 14:18:01 -0500, "Larry Bates" <(E-Mail Removed)> wrote:

>Actually the result is exactly as expected.
>Programming 101 teaches us not to reuse
>loop variables in nested loops.
>

[14:07] C:\pywk\clp>type p101.cpp
#include <cstdio>
void main(){
char abc[]="abc";
for(int i=0;i<3;++i){
printf("%c ", abc[i]);
for(int i=0;i<3;++i) printf("%d ", i);
}
}

[14:07] C:\pywk\clp>cl p101.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8168 for 80x86

p101.cpp
Microsoft (R) Incremental Linker Version 6.00.8168

/out101.exe
p101.obj

[14:07] C:\pywk\clp>p101
a 0 1 2 b 0 1 2 c 0 1 2

Regards,
Bengt Richter

Bengt Richter
Guest
Posts: n/a

 09-23-2004
On 23 Sep 2004 21:09:26 GMT, (E-Mail Removed) (Bengt Richter) wrote:

>On Thu, 23 Sep 2004 14:18:01 -0500, "Larry Bates" <(E-Mail Removed)> wrote:
>
>>Actually the result is exactly as expected.
>>Programming 101 teaches us not to reuse
>>loop variables in nested loops.
>>

>
>[14:07] C:\pywk\clp>type p101.cpp
>#include <cstdio>
>void main(){
> char abc[]="abc";
> for(int i=0;i<3;++i){
> printf("%c ", abc[i]);
> for(int i=0;i<3;++i) printf("%d ", i);
> }
>}
>
>
>[14:07] C:\pywk\clp>cl p101.cpp
>Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8168 for 80x86
>
>p101.cpp
>Microsoft (R) Incremental Linker Version 6.00.8168
>
>/out101.exe
>p101.obj
>
>[14:07] C:\pywk\clp>p101
>a 0 1 2 b 0 1 2 c 0 1 2
>
>
>
>Regards,
>Bengt Richter

Oops, I gave too much credit to M\$ ;-/
Reordering the above as below, it gives

[14:24] C:\pywk\clp>cl/nologo p101.cpp
p101.cpp

[14:38] C:\pywk\clp>p101
0 1 2 0 1 2 0 1 2

vs g++ from mingw using msys shell:

[14:35] /c/pywk/clp>cat -n p101.cpp
1 #include <cstdio>
2 int main(){
3 char abc[]="abc";
4 for(int i=0;i<3;++i){
5 for(int i=0;i<3;++i) printf("%d ", i);
6 printf("%c ", abc[i]);
7 }
8 return 0;
9 }
10
[14:35] /c/pywk/clp>g++ p101.cpp -o p101a.exe
p101.cpp: In function `int main()':
p101.cpp:6: warning: name lookup of `i' changed
p101.cpp:4: warning: matches this `i' under ISO standard rules
p101.cpp:5: warning: matches this `i' under old rules
[14:35] /c/pywk/clp>p101a
0 1 2 a 0 1 2 b 0 1 2 c [14:36] /c/pywk/clp>
[14:36] /c/pywk/clp>

Regards,
Bengt Richter

John J. Lee
Guest
Posts: n/a

 09-25-2004
Paul Rubin <http://(E-Mail Removed)> writes:

> "Larry Bates" <(E-Mail Removed)> writes:
> > Actually the result is exactly as expected. Programming 101 teaches
> > us not to reuse loop variables in nested loops.

>
> Programming 101 usually doesn't say whether a nested loop introduces a
> new scope or not. If there's a new scope, it's not re-use of a variable.

Whether the OP's usage is "re-use of a variable" is a matter of how
you choose to define the words in that phrase, I suppose. But even in
a hypothetical Python-like language that works the way Grzegorz
expected, whatever you choose to call the usage of the name i in G's
example, I call it "a bad idea".

I assume you didn't mean to imply that the OP's example wouldn't be
better if written with a differently-named loop variable, even in such
a language?:

>>> for i in ('a','b','c'):

.... for j in (1,2,3):
.... print j,
.... print i,
....
1 2 3 a 1 2 3 b 1 2 3 c

John