for x in... x remains global

Discussion in 'Python' started by Antoine De Groote, Nov 8, 2006.

  1. for x in range(3): pass

    After this statement is executed x is global variable. This seems very
    unnatural to me and caused me 3 three days of debugging because I was
    unintentionally using x further down in my program (typo). I would have
    thought that variables like this are local to the for block.

    Is there a reason this is not the case? Maybe there are PEPs or
    something else about the matter that you can point me to?

    Regards,
    antoine
    Antoine De Groote, Nov 8, 2006
    #1
    1. Advertising

  2. Antoine De Groote wrote:

    > for x in range(3): pass
    >
    > After this statement is executed x is global variable. This seems very
    > unnatural to me and caused me 3 three days of debugging because I was
    > unintentionally using x further down in my program (typo). I would have
    > thought that variables like this are local to the for block.
    >
    > Is there a reason this is not the case? Maybe there are PEPs or
    > something else about the matter that you can point me to?


    It's an somewhat unfortunate fact that loop variables leak to the outer
    scope. List-comps as well, btw.

    In

    http://www.python.org/dev/peps/pep-0289/

    it says that this will be remedied in Py3K

    """
    List comprehensions also "leak" their loop variable into the surrounding
    scope. This will also change in Python 3.0, so that the semantic definition
    of a list comprehension in Python 3.0 will be equivalent to list(<generator
    expression>). Python 2.4 and beyond should issue a deprecation warning if a
    list comprehension's loop variable has the same name as a variable used in
    the immediately surrounding scope.
    """

    And while I can't make an authorative statement about this, I can imagine
    that it won't be fixed anywhere in python2.X, as code like this is
    certainly to be found:

    for x in some_xes:
    if condition(x):
    break

    print x


    Diez
    Diez B. Roggisch, Nov 8, 2006
    #2
    1. Advertising

  3. Antoine De Groote

    Duncan Booth Guest

    Antoine De Groote <> wrote:

    > for x in range(3): pass
    >
    > After this statement is executed x is global variable. This seems very
    > unnatural to me and caused me 3 three days of debugging because I was
    > unintentionally using x further down in my program (typo). I would have
    > thought that variables like this are local to the for block.


    Blocks in Python never create new scopes. You have global variables for
    each module and one set of local variables for each function. There is a
    minor exception in that the control variables in generator expressions are
    in a separate scope, but variables are never local to a block.

    > Is there a reason this is not the case? Maybe there are PEPs or
    > something else about the matter that you can point me to?


    One good reason is that sometimes you want to use the loop variable after
    the end of the loop:

    for x in somesequence:
    if somecondition(x):
    break
    else:
    raise NotFoundError
    print "found", x

    Try to write lots of small functions and then you can keep the scope of
    variables suitably small.
    Duncan Booth, Nov 8, 2006
    #3
  4. Antoine De Groote

    Ben Finney Guest

    Antoine De Groote <> writes:

    > for x in range(3): pass
    >
    > After this statement is executed x is global variable.


    Not exactly. The name 'x' is bound at the scope of the 'for'
    statement, and remains bound after the 'for' statement stops, just as
    it would be if it was bound in any other statement.

    > This seems very unnatural to me and caused me 3 three days of
    > debugging because I was unintentionally using x further down in my
    > program (typo).


    This is, when used intentionally, one of the main useful features of
    this behaviour: to determine where an iteration stopped by using the
    value bound to the name ('x' in this case) after the iteration
    statement.

    > I would have thought that variables like this are local to the for
    > block.


    They're bound at the scope of the 'for' statement. They're available
    inside the suite of that statement.

    > Is there a reason this is not the case? Maybe there are PEPs or
    > something else about the matter that you can point me to?


    This message addresses it:

    <URL:http://mail.python.org/pipermail/python-dev/2006-April/064624.html>

    A search for the separate terms "python iteration variable scope" will
    turn up more.

    --
    \ "The best way to get information on Usenet is not to ask a |
    `\ question, but to post the wrong information." -- Aahz |
    _o__) |
    Ben Finney
    Ben Finney, Nov 8, 2006
    #4
  5. Antoine De Groote

    Guest

    Diez> It's an somewhat unfortunate fact that loop variables leak to the
    Diez> outer scope. List-comps as well, btw.

    It's unfortunate that loop variables leak from list comprehensions (they
    don't leak in genexps). It's by design in for loops though. Consider:

    for i in range(10):
    if i*i == 9:
    break
    print i

    In this silly example, the loop index is the useful value of the
    computation. You could assign to a different variable, though that would be
    slightly ugly:

    for i in range(10:
    j = i
    if j*j == 9:
    break
    print j

    Skip
    , Nov 8, 2006
    #5
    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. vMike
    Replies:
    1
    Views:
    472
    Natty Gur
    Aug 26, 2003
  2. vMike
    Replies:
    1
    Views:
    346
    Natty Gur
    Aug 26, 2003
  3. Chris
    Replies:
    1
    Views:
    308
    bruce barker
    Apr 12, 2004
  4. \Rob\
    Replies:
    0
    Views:
    416
    \Rob\
    May 10, 2004
  5. Tim Marsden
    Replies:
    11
    Views:
    949
    Steven Cheng[MSFT]
    Jun 3, 2004
Loading...

Share This Page