Saving the current value of a variable for later use in a local scope
<p>I want to to create functions in a loop, depending on the loop variable (for use with PyQT), but the functions are not "dereferencing" the loop variable as I want. (I don't know the proper terminology, so forgive my sloppiness.) This is a simple example:</p>

<pre><code>a = [1, 2, 3, 4]
b = []

for item in a:
    func = lambda: print(item)
    b.append(func)

print(a)
for func in b:
  func()
</code></pre>

<p>I'd want <code>b</code> to be a list of functions, each printing the corresponding element of <code>a</code> (at the time of definition, they shouldn't change if <code>a</code> is modified later). As suggested in the links, <code>func = lambda item=item: print(item)</code> fixes this simple case, but I can't make my PyQT case work with the same fix:</p>

<pre><code>import sys
import xml.etree.ElementTree as ET
from PyQt4 import QtCore, QtGui

class Main(QtGui.QMainWindow):
    def __init__(self, parent=None):
        QtGui.QMainWindow.__init__(self, parent)
        self.tree = ET.fromstring('&lt;root&gt;&lt;a&gt;1&lt;/a&gt;&lt;a&gt;2&lt;/a&gt;&lt;a&gt;3&lt;/a&gt;&lt;a&gt;4&lt;/a&gt;&lt;/root&gt;')
        self.create_widgets()
        self.w = None

    def create_widgets(self):
        self.buttons = []

        # THIS DOESN'T WORK
        for value in self.tree.findall('a'):
            button = QtGui.QPushButton(value.text)
            button.clicked.connect(lambda x=value: self.print_text(x))
            self.buttons.append(button)

        # THIS DOES WORK:
        #values = []
        #for value in self.tree.findall('a'):
        #    values.append(value)
        #button = QtGui.QPushButton(values[0].text)
        #button.clicked.connect(lambda: self.print_text(values[0]))
        #self.buttons.append(button)
        #button = QtGui.QPushButton(values[1].text)
        #button.clicked.connect(lambda: self.print_text(values[1]))
        #self.buttons.append(button)
        #button = QtGui.QPushButton(values[2].text)
        #button.clicked.connect(lambda: self.print_text(values[2]))
        #self.buttons.append(button)
        #button = QtGui.QPushButton(values[3].text)
        #button.clicked.connect(lambda: self.print_text(values[3]))
        #self.buttons.append(button)

        box = QtGui.QHBoxLayout()
        for i in self.buttons:
            box.addWidget(i)
        central_widget = QtGui.QWidget()
        central_widget.setLayout(box)
        self.setCentralWidget(central_widget)

    def print_text(self, value):
        print(value)
        print(value.text)

if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    myapp = Main()
    myapp.show()
    sys.exit(app.exec_())
</code></pre>

<p>I want to pass an <code>xml.etree</code> element, but if I use the lambda function, what I get is only <code>False</code>. With explicit creation of each button, everything works fine.</p>