Home > Blockchain >  Unable to append entry to list when using lambda
Unable to append entry to list when using lambda

Time:03-10

I am having issues trying to append an entry I receive from the user input from tkinter. I found some code online which uses a lambda to send each set of entries to the screen which I modified to serve my purposes. It is not acting as expected though.

Example input:

Channel: 101
Serial: 123

Then I press the "Next" button and my first result is:

[['Chamber 6', 'DL 7'], ['Chan 101 (VDC)', '123']]

Which is what I expect. The issue is when I add another entry.

Second Input:

Channel: 103
Serial: 456

Then I press the next button again and my second result is:

[['Chamber 6', 'DL 7'], ['Chan 103 (VDC)', '456'], ['Chan 103 (VDC)', '456']]

It will always append the last list x number of times, instead of appending the modified list each time. I get the same result when using a numpy array as well.

Below is my code. Can someone explain what I need to do to get around this? Thanks in advance!

# importing module
from pandas import *
import numpy as np
import tkinter as tk

fields = 'Channel', 'Serial'

chan_data = [['Chamber 6', 'DL 7']]

temp_arr = ['','']

def fetch(entries):
    for entry in entries:
        field = entry[0]
        text  = entry[1].get()
        if field =='Channel':
            temp_arr[0] = 'Chan '   text   ' (VDC)'
        elif field == 'Serial':
            temp_arr[1] = text
            chan_data.append(temp_arr)
            print (chan_data)

def makeform(root, fields):
    entries = []
    for field in fields:
        row = tk.Frame(root)
        lab = tk.Label(row, width=15, text=field, anchor='w')
        ent = tk.Entry(row)
        row.pack(side=tk.TOP, fill=tk.X, padx=5, pady=5)
        lab.pack(side=tk.LEFT)
        ent.pack(side=tk.RIGHT, expand=tk.YES, fill=tk.X)
        entries.append((field, ent))
    return entries

if __name__ == '__main__':
    root = tk.Tk()
    ents = makeform(root, fields)
    root.bind('<Return>', (lambda event, e=ents: fetch(e)))   
    b1 = tk.Button(root, text='Next',command=(lambda e=ents: fetch(e)))
    b1.pack(side=tk.LEFT, padx=5, pady=5)
    b2 = tk.Button(root, text='Quit', command=root.destroy)
    b2.pack(side=tk.LEFT, padx=5, pady=5)
    root.mainloop()

I am using Spyder as my IDE and I am working with Python 3.7.9.

CodePudding user response:

The issue was temp_arr = ['','']

It simply needed to be moved inside the method because it was referencing the same object x number of times.

def fetch(entries):
    temp_arr = ['','']                 <-----------
    for entry in entries:
        field = entry[0]
        text  = entry[1].get()
        if field =='Channel':
            temp_arr[0] = 'Chan '   text   ' (VDC)'
        elif field == 'Serial':
            temp_arr[1] = text
            chan_data.append(temp_arr)
            print (chan_data)

CodePudding user response:

To fix this, you need to copy the list when passing it to append:

#Three ways to copy
chan_data.append(temp_arr.copy())
chan_data.append(list(temp_arr))
chan_data.append(temp_arr[:])

The list temp_arr is being appended by reference, so changing the original temp_arr list changes the lists in chan_data since they are just references to temp_arr. Calling copy() or list() creates a new list; changing temp_arr doesn't change the copied list.

  • Related