Unexpected result.

Discussion in 'Python' started by Grzegorz Dostatni, Sep 23, 2004.

  1. 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)
     
    Grzegorz Dostatni, Sep 23, 2004
    #1
    1. Advertising

  2. Grzegorz Dostatni

    Larry Bates Guest

    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


    "Grzegorz Dostatni" <> wrote in message
    news:p...
    >
    > 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, Sep 23, 2004
    #2
    1. Advertising

  3. 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
     
    Steven Bethard, Sep 23, 2004
    #3
  4. Grzegorz Dostatni

    Paul Rubin Guest

    "Larry Bates" <> 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.
     
    Paul Rubin, Sep 23, 2004
    #4
  5. Grzegorz Dostatni

    Andrew Dalke Guest

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

    Andrew
     
    Andrew Dalke, Sep 23, 2004
    #5
  6. 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
     
    Steven Bethard, Sep 23, 2004
    #6
  7. On Thu, 23 Sep 2004 14:18:01 -0500, "Larry Bates" <> 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);
    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
     
    Bengt Richter, Sep 23, 2004
    #7
  8. On 23 Sep 2004 21:09:26 GMT, (Bengt Richter) wrote:

    >On Thu, 23 Sep 2004 14:18:01 -0500, "Larry Bates" <> 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);
    > 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
     
    Bengt Richter, Sep 23, 2004
    #8
  9. Grzegorz Dostatni

    John J. Lee Guest

    Paul Rubin <http://> writes:

    > "Larry Bates" <> 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
     
    John J. Lee, Sep 25, 2004
    #9
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Mike Pemberton

    unexpected result using std::list

    Mike Pemberton, Oct 14, 2003, in forum: C++
    Replies:
    3
    Views:
    351
    Dan Cernat
    Oct 14, 2003
  2. John J

    Unexpected Result

    John J, May 12, 2004, in forum: C++
    Replies:
    8
    Views:
    389
    John J
    May 13, 2004
  3. japh
    Replies:
    4
    Views:
    750
  4. Michael Tan
    Replies:
    32
    Views:
    1,021
    Ara.T.Howard
    Jul 21, 2005
  5. Andy Tolle
    Replies:
    7
    Views:
    237
    Andy Tolle
    Nov 15, 2010
Loading...

Share This Page