Python issue editing tkinter canvas items in a 2darray
Question: I'm using a raspberry pi as a communication front end for more complex
devices. I'm coding it in python, and including a gui to display the
information going through it.

My issue involves a grid of canvas text items of size 4x4, as referenced by a
2d array `dataText[][]`. I am editing the items using `itemconfigure()` to
update the displayed data.

The issue: when i update `dataText[y][x]`, no matter the numbers, it updates
the item at position (3,x) instead.

Demonstrative code:

    
    
    from Tkinter import *
    from ttk import Style
    
    #gui class (tkinter loop)
    class UI(Frame):
        #data value field
        dataText = [[0]*4]*4
    
        def __init__(self, parent):
            Frame.__init__(self, parent)
    
            self.parent = parent
    
            self.initUI()
    
        def initUI(self):
    
            #sets up the main window
            self.parent.title("Power Converter Controller")
            self.style = Style()
            self.style.theme_use("default")
            self.pack(fill=BOTH, expand=YES)
    
            #configures padding along columns and rows
            for i in range(4):
                self.columnconfigure(i, pad=3, weight=1)
            for i in range(7):
                self.rowconfigure(i, pad=3, weight=1)
    
            #creates a canvas at the top of the window. The canvas is used for
            #displaying data
            self.display = Canvas(self, width=600, height=170)
            self.display.grid(column=0, row=0, columnspan=4, rowspan=4)
    
            #draws canvas items that can be updated
            self.dynamicCanvasItems(self.display)
    
        def dynamicCanvasItems(self, canvas):
    
            #initializes the grid text handles
            for i in range(4):
                for j in range(4):
                    self.dataText[i][j] = canvas.create_text(75*(j+1),25*(i+1),text = data[i][j], font=("Helvetica",20))
    
            for i in range(4):
                for j in range(4):
                    self.display.itemconfigure(self.dataText[i][j], text=5)
    
    def main():
    
        global root
        global data
    
        #initialize 2d data array
        data = [[x]*4 for x in xrange(4)]
    
        #initialize the ui loop
        root = Tk()
        root.geometry("600x300+600+300")
        ui = UI(root)
    
        #enter the ui loop
        root.mainloop()
    
    if __name__ == '__main__':
        main()
    

The whole program is rather large, so I've cut out irrelevant portions. I made
sure that the redacted portions had no effect on the issue (by disabling them
and checking if the problem changed).

in the `dynamicCanvasItems()` method, the widgets are set up correctly. If you
disable the second dual for-loop, it displays this:

    
    
    0    0    0    0
    1    1    1    1
    2    2    2    2
    3    3    3    3
    

So the second dual for-loop should overwrite all of the widgets with 5.
However, this happens:

    
    
    0    0    0    0
    1    1    1    1
    2    2    2    2
    5    5    5    5
    

Does anyone know why?


Answer: It is because your initialization code is creating a list of lists, where each
sublist is a reference to the same object. You don't have a list of four
different sublists, you have a list of four references to the same list.

To prove this, add the following right after you initialize `dataText`:

    
    
    print [id(x) for x in dataText]
    

You'll see that all four lists have the exact same internal id, meaning they
all reference the exact same list.

Compare what happens when you change your initialization code to this:

    
    
    dataText = [
        [0,0,0,0],
        [0,0,0,0],
        [0,0,0,0],
        [0,0,0,0]
        ]
    

In the above, you are explicitly creating four unique lists, each with four
unique values.

