After alot of research including on on stackoverflow i really can't understand why the code below does not work even after i set the Default value of my variable as alot of people recomended. here is the code
#initial nested array
outter = [["name1",1],["name2",2],["name3",3]]
for inner in outter:
button = QPushButton()
button.setText(inner[0]) // create a button with the text
button.clicked.connect(lambda value=inner[1] : print(value))
The 3 buttons are created each with its respective name ( name1,name2,name3) but when i click them, it prints
False
False
False
If i change this part of the code, all 3 buttons print the last value "3", as shown below,
button.clicked.connect(lambda : print(inner[1]))
3
3
3
I already tried doing all sorts crazy things to make this work, any advices?
I suppose you plainly forgot to press "save" after adding the value=…
stuff.
If I replay your problem
outer = [["name1",1],["name2",2],["name3",3]]
# this must have been your original approach and was the same as in the linked question
ll = [lambda: inner[1] for inner in outer]
print(ll[0](), ll[1](), ll[2]()) # gives 3 3 3
# your approach
ll = [lambda value=inner[1]: value for inner in outer]
print(ll[0](), ll[1](), ll[2]()) # gives 1 2 3
# alternative approach
ll = [lambda value=inner: value[1] for inner in outer]
print(ll[0](), ll[1](), ll[2]()) # gives 1 2 3
As was mentioned in the previously linked question, the lambda always accesses the inner
variable via its closure, only getting its last and persisting value.
The alternative approaches go the way to link the lambda to the value which is current at creation time and should definitely work. (Note that instead of doung things with buttons, I concentrate on the labda problem.)
Another way could be to have a function which creates "printers" as needed:
def printer(value):
return lambda: print(value)
With them, you can easily create lambdas which do as you want: print the given value, such as
button.clicked.connect(printer(inner[1]))print(value))