Home > Blockchain >  Why is the variable always set to the last item in the list? [duplicate]
Why is the variable always set to the last item in the list? [duplicate]

Time:09-17

Using tkinter and python to build a GUI and I'm adding buttons using globals() based off a list of room_types. However, the variable I'm passing into the button's command is always the last item on the list, even though every other instance of using room_type[i] correlates to the correct element.

This is what I'm having problems with.

from tkinter import *

root = Tk()

room_type = ['kitchen', 'living_room', 'bedroom', 'bathroom', 'study', 'laundry', 'dining_room']


def new_room(r):
    print(r)


for i in range(len(room_type)):
    globals()[f'{room_type[i]}_add'] = Button(root, text='Add a '   room_type[i],
                                              command=lambda: new_room(r=room_type[i]))
    globals()[f'{room_type[i]}_add'].grid(row=1, column=i)

root.mainloop()

It makes 7 buttons, each with text that indicates the different room types, but for some reason, r always equals the last element in the list. In this case, dining_room.

CodePudding user response:

Capture the current value of i when declaring the lambda:

from tkinter import *

root = Tk()

room_type = ['kitchen', 'living_room', 'bedroom', 'bathroom', 'study', 'laundry', 'dining_room']


def new_room(r):
    print(r)


for i in range(len(room_type)):
    globals()[f'{room_type[i]}_add'] = Button(root, text='Add a '   room_type[i],
                                              command=lambda pi=i: new_room(r=room_type[pi]))
    globals()[f'{room_type[i]}_add'].grid(row=1, column=i)

root.mainloop()

CodePudding user response:

The use of lamda is making another loop of function which stops at the end of the last items and thus for every loop it stays the last i. Try removing the lamda and check out.

from tkinter import *

root = Tk()

room_type = ['kitchen', 'living_room', 'bedroom', 'bathroom', 'study', 'laundry', 'dining_room']


def new_room(r):
    print(r)


for i in range(len(room_type)):
    globals()[f'{room_type[i]}_add'] = Button(root, text='Add a '   room_type[i],
                                              command=new_room(r=room_type[i]))
    globals()[f'{room_type[i]}_add'].grid(row=1, column=i)

root.mainloop()
  • Related