diff options
author | Ezio Melotti <ezio.melotti@gmail.com> | 2013-01-04 22:51:20 (GMT) |
---|---|---|
committer | Ezio Melotti <ezio.melotti@gmail.com> | 2013-01-04 22:51:20 (GMT) |
commit | 7d4866908524f9dbdd3786ebe2ea3ad3b44c01ff (patch) | |
tree | 161ddeb6805bf7097a8a6ec790176ce5f265d2d8 | |
parent | 6c83e739d7b1690f8763b2437266effa71173324 (diff) | |
parent | cad8b0ff8edc2dd6437ee1022977358a16f3860e (diff) | |
download | cpython-7d4866908524f9dbdd3786ebe2ea3ad3b44c01ff.zip cpython-7d4866908524f9dbdd3786ebe2ea3ad3b44c01ff.tar.gz cpython-7d4866908524f9dbdd3786ebe2ea3ad3b44c01ff.tar.bz2 |
#13094: merge with 3.2.
-rw-r--r-- | Doc/faq/programming.rst | 52 | ||||
-rw-r--r-- | Misc/NEWS | 3 |
2 files changed, 55 insertions, 0 deletions
diff --git a/Doc/faq/programming.rst b/Doc/faq/programming.rst index aac8e81..32123de 100644 --- a/Doc/faq/programming.rst +++ b/Doc/faq/programming.rst @@ -206,6 +206,58 @@ an imported module. This clutter would defeat the usefulness of the ``global`` declaration for identifying side-effects. +Why do lambdas defined in a loop with different values all return the same result? +---------------------------------------------------------------------------------- + +Assume you use a for loop to define a few different lambdas (or even plain +functions), e.g.:: + + squares = [] + for x in range(5): + squares.append(lambda: x**2) + +This gives you a list that contains 5 lambdas that calculate ``x**2``. You +might expect that, when called, they would return, respectively, ``0``, ``1``, +``4``, ``9``, and ``16``. However, when you actually try you will see that +they all return ``16``:: + + >>> squares[2]() + 16 + >>> squares[4]() + 16 + +This happens because ``x`` is not local to the lambdas, but is defined in +the outer scope, and it is accessed when the lambda is called --- not when it +is defined. At the end of the loop, the value of ``x`` is ``4``, so all the +functions now return ``4**2``, i.e. ``16``. You can also verify this by +changing the value of ``x`` and see how the results of the lambdas change:: + + >>> x = 8 + >>> squares[2]() + 64 + +In order to avoid this, you need to save the values in variables local to the +lambdas, so that they don't rely on the value of the global ``x``:: + + squares = [] + for x in range(5): + squares.append(lambda n=x: n**2) + +Here, ``n=x`` creates a new variable ``n`` local to the lambda and computed +when the lambda is defined so that it has the same value that ``x`` had at +that point in the loop. This means that the value of ``n`` will be ``0`` +in the first lambda, ``1`` in the second, ``2`` in the third, and so on. +Therefore each lambda will now return the correct result:: + + >>> squares[2]() + 4 + >>> squares[4]() + 16 + +Note that this behaviour is not peculiar to lambdas, but applies to regular +functions too. + + How do I share global variables across modules? ------------------------------------------------ @@ -456,6 +456,9 @@ Tools/Demos Documentation ------------- +- Issue #13094: add "Why do lambdas defined in a loop with different values + all return the same result?" programming FAQ. + - Issue #14901: Update portions of the Windows FAQ. Patch by Ashish Nitin Patil. |