loop scope

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Arthur

    loop scope

    [color=blue][color=green][color=darkred]
    >>>a=[1,2,3]
    >>> for p in a:[/color][/color][/color]
    print p
    1
    2
    3[color=blue][color=green][color=darkred]
    >>> p[/color][/color][/color]
    3

    My naive expectation was that p would be 'not defined' from outside
    the loop.

    I know this is not news.

    In fact I had come across some discussion of this fact, but apparently
    didn't register it.

    As I got myself surprised by it - specifically in the context of list
    comps, where I think it is particularly surprising:
    [color=blue][color=green][color=darkred]
    >>> b=[4,5,6]
    >>> [t*2 for t in b][/color][/color][/color]
    [8, 10, 12][color=blue][color=green][color=darkred]
    >>> t[/color][/color][/color]
    6

    Is this anywhere useful, or more of an artifact?

    Art

  • Terry Reedy

    #2
    Re: loop scope


    "Arthur" <ajsiegel@opton line.com> wrote in message
    news:f8k150pgq5 ndk1q0s8s3vmgcu si7pl7b12@4ax.c om...[color=blue]
    >[color=green][color=darkred]
    > >>>a=[1,2,3]
    > >>> for p in a:[/color][/color]
    > print p
    > 1
    > 2
    > 3[color=green][color=darkred]
    > >>> p[/color][/color]
    > 3
    >
    > My naive expectation was that p would be 'not defined' from outside
    > the loop.
    >
    > I know this is not news.
    >
    > In fact I had come across some discussion of this fact, but apparently
    > didn't register it.
    >
    > As I got myself surprised by it - specifically in the context of list
    > comps, where I think it is particularly surprising:
    >[color=green][color=darkred]
    > >>> b=[4,5,6]
    > >>> [t*2 for t in b][/color][/color]
    > [8, 10, 12][color=green][color=darkred]
    > >>> t[/color][/color]
    > 6
    >
    > Is this anywhere useful, or more of an artifact?[/color]

    For loops with a break statement, the value of the loop index when the
    break occurs may be the answer sought or needed to calculate it. For list
    comps which cannot have break, it is an artifact which may disappear in
    2.4.

    Terry J. Reedy




    Comment

    • David MacQuigg

      #3
      Re: loop scope

      On Thu, 11 Mar 2004 21:08:09 GMT, Arthur <ajsiegel@opton line.com>
      wrote:
      [color=blue]
      >[color=green][color=darkred]
      >>>>a=[1,2,3]
      >>>> for p in a:[/color][/color]
      > print p
      >1
      >2
      >3[color=green][color=darkred]
      >>>> p[/color][/color]
      >3
      >
      >My naive expectation was that p would be 'not defined' from outside
      >the loop.
      >
      >I know this is not news.
      >
      >In fact I had come across some discussion of this fact, but apparently
      >didn't register it.
      >
      >As I got myself surprised by it - specifically in the context of list
      >comps, where I think it is particularly surprising:
      >[color=green][color=darkred]
      >>>> b=[4,5,6]
      >>>> [t*2 for t in b][/color][/color]
      >[8, 10, 12][color=green][color=darkred]
      >>>> t[/color][/color]
      >6
      >
      >Is this anywhere useful, or more of an artifact?[/color]

      Scopes are defined by the boundaries of functions, classes and
      modules, not for loops. This is essential, or you would have to
      declare global variables inside most for loops.

      For a good, up-to-date discussion of scopes, see Learning Python, Ch.
      13 Scopes and Arguments, and p.337 - Namespaces: The Whole Story. Be
      sure to get the 2nd edition. The scope rules have changed
      significantly since the first edition.

      -- Dave

      Comment

      • user@domain.invalid

        #4
        Re: loop scope

        Terry Reedy wrote:
        [color=blue]
        > For loops with a break statement, the value of the loop index when the
        > break occurs may be the answer sought or needed to calculate it. For list
        > comps which cannot have break, it is an artifact which may disappear in
        > 2.4.[/color]

        If I understand you, I don't think I like this idea. It
        adds complexity to the mental model of a loop. "The
        loop variable disappears when the loop ends unless the
        loop contains a break".

        In my opinion, Python should pick a model and stick to
        it. Loop variables are either ordinary variables that
        exist until you explicitly delete them, or they are
        special variables that automagically disappear at the
        end of the loop. I vote for the first one.


        --
        Steven D'Aprano


        Comment

        • Donn Cave

          #5
          Re: loop scope

          Quoth user@domain.inv alid:
          | Terry Reedy wrote:
          |
          |> For loops with a break statement, the value of the loop index when the
          |> break occurs may be the answer sought or needed to calculate it. For list
          |> comps which cannot have break, it is an artifact which may disappear in
          |> 2.4.
          |
          | If I understand you, I don't think I like this idea. It
          | adds complexity to the mental model of a loop. "The
          | loop variable disappears when the loop ends unless the
          | loop contains a break".
          |
          | In my opinion, Python should pick a model and stick to
          | it. Loop variables are either ordinary variables that
          | exist until you explicitly delete them, or they are
          | special variables that automagically disappear at the
          | end of the loop. I vote for the first one.

          That makes sense to me, but I read "For list comps" as "For list
          comprehensions (but not conventional loops.)" List comprehensions
          shouldn't need to have every side effect of the equivalent loop.

          Donn Cave, donn@drizzle.co m

          Comment

          • Arthur

            #6
            Re: loop scope

            On Thu, 11 Mar 2004 17:54:56 -0700, David MacQuigg <dmq@gain.com >
            wrote:[color=blue][color=green]
            >>[color=darkred]
            >>>>> b=[4,5,6]
            >>>>> [t*2 for t in b][/color]
            >>[8, 10, 12][color=darkred]
            >>>>> t[/color]
            >>6
            >>
            >>Is this anywhere useful, or more of an artifact?[/color]
            >
            >Scopes are defined by the boundaries of functions, classes and
            >modules, not for loops. This is essential, or you would have to
            >declare global variables inside most for loops.[/color]

            I am not following this argument. The surprise, specifically, is
            that I don't think of myself as having declared "t" as a variable. it
            is don't magically, as a placeholder and for a very specific purpose.
            So I would expect it to go away outside of the " [ " and " ] " by
            equal and opposite magic.

            I ran into the issue while playing at the prompt. Running the same
            statement I had run previously gave me a different result than before.
            Surprising. Yes I had tested a list comp, in between. Because I have
            been around the language for some time, and have my ear to the ground,
            it didn't take me long to understand what was happening.

            Flabbergasted, rather than surprised, might have otherwise been the
            reaction.

            Art

            Comment

            • Terry Reedy

              #7
              Re: loop scope

              <user@domain.in valid> wrote in message
              news:405148CB.1 030103@domain.i nvalid...[color=blue]
              > Terry Reedy wrote:
              >[color=green]
              >> For list comps which cannot have break,
              >> it is an artifact which may disappear in 2.4.[/color]
              >
              > If I understand you,[/color]

              I don't think you did. The 'may' only applies to list comprehensions. The
              discussion last fall was whether the index names(s) within a list
              comprehension should be bound outside (after) the list comp. It is
              something of an accident of the current implementation that they are. The
              issue arose in the development of generator comprehensions, in which it was
              clear that the within-generator variables would *not* be bound outside of
              the produced generator. Bret Cannon's summary

              is this:

              ---------------
              A quick example is:

              (x for x in range(10) if x%2)

              returns an iterator that returns the odd numbers from 0 to 10. This make
              list comprehensions just syntactic sugar for passing a generator expression
              to list() (note how extra parentheses are not needed):

              list(x for x in range(10) is x%2)

              Having list comprehensions defined this way also takes away the dangling
              item variable for the 'for' loop. Using that dangling variable is now
              discouraged and will be made illegal at some point.
              ----------------

              Terry J. Reedy




              Comment

              • Isaac To

                #8
                Re: loop scope

                >>>>> "Arthur" == Arthur <ajsiegel@opton line.com> writes:

                Arthur> I am not following this argument. The surprise, specifically,
                Arthur> is that I don't think of myself as having declared "t" as a
                Arthur> variable. it is don't magically, as a placeholder and for a
                Arthur> very specific purpose. So I would expect it to go away outside
                Arthur> of the " [ " and " ] " by equal and opposite magic.

                I remember I've read that this more proper scoping for list comprehension
                will take effect in a future version of Python.

                Regards,
                Isaac.

                Comment

                • David MacQuigg

                  #9
                  Re: loop scope

                  On Fri, 12 Mar 2004 14:06:38 GMT, Arthur <ajsiegel@opton line.com>
                  wrote:
                  [color=blue]
                  >On Thu, 11 Mar 2004 17:54:56 -0700, David MacQuigg <dmq@gain.com >
                  >wrote:[/color]
                  [color=blue][color=green]
                  >>Scopes are defined by the boundaries of functions, classes and
                  >>modules, not for loops. This is essential, or you would have to
                  >>declare global variables inside most for loops.[/color]
                  >
                  >I am not following this argument. The surprise, specifically, is
                  >that I don't think of myself as having declared "t" as a variable. it
                  >is don't magically, as a placeholder and for a very specific purpose.
                  >So I would expect it to go away outside of the " [ " and " ] " by
                  >equal and opposite magic.[/color]

                  The "declaratio ns" are automatic, whenever you *use* a variable. I
                  would *not* expect temporary variables in a loop to go away outside of
                  the loop. It's just another variable in the current namespace.

                  I think I may have misunderstood your original question. The title of
                  the thread is 'loop scope', but your question seems to be specifically
                  on the loop iteration variable 't'. Just think of it as a normal
                  variable in the current local scope.

                  The one exception I can think of is what Terry Reedy mentioned - the
                  iteration variable in a list comprehension. In some future
                  optimization, they may neglect to save that variable. I hope they
                  don't do that (even though it really has no use). I just like the
                  consistency we now have in treatment of all local variables.

                  -- Dave

                  Comment

                  • Mel Wilson

                    #10
                    Re: loop scope

                    In article <kdg3505p3qj8t3 85htgcr88gkr3jc eej98@4ax.com>,
                    Arthur <ajsiegel@opton line.com> wrote:[color=blue]
                    >On Thu, 11 Mar 2004 17:54:56 -0700, David MacQuigg <dmq@gain.com >
                    >wrote:[color=green]
                    >>Scopes are defined by the boundaries of functions, classes and
                    >>modules, not for loops. This is essential, or you would have to
                    >>declare global variables inside most for loops.[/color]
                    >
                    >I am not following this argument. The surprise, specifically, is
                    >that I don't think of myself as having declared "t" as a variable. it
                    >is don't magically, as a placeholder and for a very specific purpose.
                    >So I would expect it to go away outside of the " [ " and " ] " by
                    >equal and opposite magic.[/color]

                    Well, you don't declare variables in Python. You use
                    names to refer to objects. Python 2.4 may give each list
                    comprehension its own namespace, but for now names used in a
                    list comp. are used just as they would be in any other
                    statement.

                    Regards. Mel.

                    Comment

                    • Jacek Generowicz

                      #11
                      Re: loop scope

                      David MacQuigg <dmq@gain.com > writes:
                      [color=blue]
                      > On Fri, 12 Mar 2004 14:06:38 GMT, Arthur <ajsiegel@opton line.com>
                      > wrote:
                      >[color=green]
                      > >On Thu, 11 Mar 2004 17:54:56 -0700, David MacQuigg <dmq@gain.com >
                      > >wrote:[/color]
                      >[color=green][color=darkred]
                      > >>Scopes are defined by the boundaries of functions, classes and
                      > >>modules, not for loops. This is essential, or you would have to
                      > >>declare global variables inside most for loops.[/color][/color][/color]
                      [color=blue]
                      > The one exception I can think of is what Terry Reedy mentioned - the
                      > iteration variable in a list comprehension. In some future
                      > optimization, they may neglect to save that variable. I hope they
                      > don't do that (even though it really has no use). I just like the
                      > consistency we now have in treatment of all local variables.[/color]

                      You can maintain that consistency by extending the list of
                      "boundaries " which define scopes; you already mentioned classes,
                      functions and modules ... now simply add list comprehensions (or
                      loops), and you will maintain perfect consistency of treatment of
                      local variables, without leaking variables out of list comprehensions
                      (or loops).

                      Comment

                      • David MacQuigg

                        #12
                        Re: loop scope

                        On 12 Mar 2004 17:13:19 +0100, Jacek Generowicz
                        <jacek.generowi cz@cern.ch> wrote:
                        [color=blue]
                        >David MacQuigg <dmq@gain.com > writes:
                        >[color=green]
                        >> On Fri, 12 Mar 2004 14:06:38 GMT, Arthur <ajsiegel@opton line.com>
                        >> wrote:
                        >>[color=darkred]
                        >> >On Thu, 11 Mar 2004 17:54:56 -0700, David MacQuigg <dmq@gain.com >
                        >> >wrote:[/color]
                        >>[color=darkred]
                        >> >>Scopes are defined by the boundaries of functions, classes and
                        >> >>modules, not for loops. This is essential, or you would have to
                        >> >>declare global variables inside most for loops.[/color][/color]
                        >[color=green]
                        >> The one exception I can think of is what Terry Reedy mentioned - the
                        >> iteration variable in a list comprehension. In some future
                        >> optimization, they may neglect to save that variable. I hope they
                        >> don't do that (even though it really has no use). I just like the
                        >> consistency we now have in treatment of all local variables.[/color]
                        >
                        >You can maintain that consistency by extending the list of
                        >"boundaries " which define scopes; you already mentioned classes,
                        >functions and modules ... now simply add list comprehensions (or
                        >loops), and you will maintain perfect consistency of treatment of
                        >local variables, without leaking variables out of list comprehensions
                        >(or loops).[/color]

                        I think the current design of Python is the right compromise between
                        narrow scopes that avoid conflicts between identical names and broad
                        scopes that minimize the need for global declarations. Imagine having
                        to declare globals inside every loop that needed to set some value
                        outside of its own tiny little scope.

                        -- Dave

                        Comment

                        • Terry Reedy

                          #13
                          Re: loop scope


                          "David MacQuigg" <dmq@gain.com > wrote in message
                          news:utn350d54p jtrsi1a6sd4ckg8 2mnq2uf4b@4ax.c om...[color=blue]
                          > The one exception I can think of is what Terry Reedy mentioned - the
                          > iteration variable in a list comprehension. In some future
                          > optimization, they may neglect to save that variable. I hope they
                          > don't do that (even though it really has no use). I just like the
                          > consistency we now have in treatment of all local variables.[/color]

                          Please see other post. In the future, the consisitency will be with
                          generator comprehensions, where the loop variable is clearly encapsulated
                          inside the induced generator function.

                          Terry J. Reedy




                          Comment

                          • Greg Ewing (using news.cis.dfn.de)

                            #14
                            Re: loop scope

                            Jacek Generowicz wrote:[color=blue]
                            > now simply add list comprehensions (or
                            > loops), and you will maintain perfect consistency of treatment of
                            > local variables,[/color]

                            It wouldn't do to make the whole (non-comprehension)
                            for-loop a new scope, because that would make any
                            variables assigned within the loop body local as well.

                            --
                            Greg Ewing, Computer Science Dept,
                            University of Canterbury,
                            Christchurch, New Zealand


                            Comment

                            • Jacek Generowicz

                              #15
                              Re: loop scope

                              David MacQuigg <dmq@gain.com > writes:
                              [color=blue][color=green]
                              > >You can maintain that consistency by extending the list of
                              > >"boundaries " which define scopes; you already mentioned classes,
                              > >functions and modules ... now simply add list comprehensions (or
                              > >loops), and you will maintain perfect consistency of treatment of
                              > >local variables, without leaking variables out of list comprehensions
                              > >(or loops).[/color]
                              >
                              > I think the current design of Python is the right compromise between
                              > narrow scopes that avoid conflicts between identical names and broad
                              > scopes that minimize the need for global declarations. Imagine having
                              > to declare globals inside every loop that needed to set some value
                              > outside of its own tiny little scope.[/color]

                              And what if the variable I want to affect is in an enclosing scope,
                              but not the global scope ?

                              Doesn't this rather suggest that the whole global declaration business
                              is rather flawed? It sort of made sense when we only had 3 scopes in
                              Python (only 2 of which were "userland" scopes) , but with nested
                              scopes it's simply not up to the job. Ultimately, the problem can be
                              traced to having no distinction between inctroducting a new binding
                              and rebinding an existing name.

                              Comment

                              Working...