Unexpected result.

G

Grzegorz Dostatni

Consider the following fragment:
.... 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)
 
L

Larry Bates

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=j

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

Larry Bates
 
S

Steven Bethard

Grzegorz Dostatni said:
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
 
P

Paul Rubin

Larry Bates said:
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.
 
A

Andrew Dalke

Grzegorz said:
> 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 == "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
.... 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
advise you do either.

Andrew
(e-mail address removed)
 
B

Bengt Richter

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);
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
Copyright (C) Microsoft Corp 1984-1998. All rights reserved.

p101.cpp
Microsoft (R) Incremental Linker Version 6.00.8168
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

/out:p101.exe
p101.obj

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

;-)

Regards,
Bengt Richter
 
B

Bengt Richter

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);
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
Copyright (C) Microsoft Corp 1984-1998. All rights reserved.

p101.cpp
Microsoft (R) Incremental Linker Version 6.00.8168
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

/out:p101.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);
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
 
J

John J. Lee

Paul Rubin said:
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 j in (1,2,3):
.... print j,
.... print i,
....
1 2 3 a 1 2 3 b 1 2 3 c



John
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,015
Latest member
AmbrosePal

Latest Threads

Top