title: What do lambda function closures capture?
body: <p>Recently I started playing around with Python and I came around something peculiar in the way closures work. Consider the following code:</p>
  <pre><code>adders=[None, None, None, None]
  
  for i in [0,1,2,3]:
     adders[i]=lambda a: i+a
  
  print adders[1](3)
  </code></pre>
  <p>It builds a simple array of functions that take a single input and return that input added by a number. The functions are constructed in <code>for</code> loop where the iterator <code>i</code> runs from <code>0</code> to <code>3</code>. For each of these numbers a <code>lambda</code> function is created which captures <code>i</code> and adds it to the function's input. The last line calls the second <code>lambda</code> function with <code>3</code> as a parameter. To my surprise the output was <code>6</code>.</p>
  <p>I expected a <code>4</code>. My reasoning was: in Python everything is an object and thus every variable is essential a pointer to it. When creating the <code>lambda</code> closures for <code>i</code>, I expected it to store a pointer to the integer object currently pointed to by <code>i</code>. That means that when <code>i</code> assigned a new integer object it shouldn't effect the previously created closures. Sadly, inspecting the <code>adders</code> array within a debugger shows that it does. All <code>lambda</code> functions refer to the last value of <code>i</code>, <code>3</code>, which results in <code>adders[1](3)</code> returning <code>6</code>.</p>
  <p>Which make me wonder about the following:</p>
  <ul>
  <li>What do the closures capture exactly?</li>
  <li>What is the most elegant way to convince the <code>lambda</code> functions to capture the current value of <code>i</code> in a way that will not be affected when <code>i</code> changes its value?</li>
  </ul>
  <hr />
  <p><sub>For a more accessible, practical version of the question, specific to the case where a loop (or list comprehension, generator expression etc.) is used, see <a href="https://stackoverflow.com/questions/3431676/creating-functions-in-a-loop">Creating functions (or lambdas) in a loop (or comprehension)</a>. This question is focused on understanding the underlying behaviour of the code in Python.</sub></p>
  <p><sub>If you got here trying to fix a problem with making buttons in Tkinter, try <a href="https://stackoverflow.com/questions/10865116/">tkinter creating buttons in for loop passing command arguments</a> for more specific advice.</sub></p>
  <p><sub>See <a href="https://stackoverflow.com/questions/14413946/">What exactly is contained within a obj.__closure__?</a> for technical details of <strong>how</strong> Python implements closures. See <a href="https://stackoverflow.com/questions/10580">What is the difference between Early and Late Binding?</a> for related terminology discussion.</sub></p>