从列表框中的选定行删除Csv文件中的行

时间:2016-03-24 02:04:44

标签: python csv tkinter listbox

我有这个小接口有一个列表框,其中包含来自bmi.csv文件的文本行我知道如何从列表框中删除该行但不知道如何从csv文件中删除该行?

Pic of the interface

我在这里使用此代码导入csv数据

with open('Bmi.csv', newline='') as f:
    reader = csv.reader(f)
    for row in reader:
        listbox.insert(END, row)
    fr.close()

这是我调用删除项目功能的按钮

mbutton = Button(text="Remove Item", command=removeitem).grid(row=3, column=1, sticky=N)

这是我的删除项功能

def removeitem():
    fr = open('Bmi.csv', 'r')
    value=str((listbox.get(ACTIVE)))
    lines = fr.readlines()
    fr.close()
    fr = open("Bmi.csv","w")
    for line in lines:
        if line!=value:
            f.write(line)
    listbox.delete(ANCHOR)
    fr.close()

我试图在行框中获取所选行的字符串然后在csv文件中搜索该字符串然后删除它但我听说我需要重新创建csv,这样做我怎么能这样做?

1 个答案:

答案 0 :(得分:1)

即使您的文件采用csv格式,它仍然使用基本文本格式,因为您只在Listbox中显示文本,根本不需要包含csv操作:

with open('Bmi.csv', newline='') as f:
    #are you sure the newline ^ should be ''?
    for row in f:
        listbox.insert(END, row)
    #fr.close() #the with statement closes f, not sure what fr is...

这样,通过将行写入列表框并以相同的方式返回到文件中,它不会更改数据,例如将[]添加到不应该的位置。

虽然这可能会破坏程序的其他功能,假设数据是作为csv加载的,但唯一的问题是csv.reader默认情况下假设数据是用逗号分隔的,但是查看您提供数据的屏幕截图看起来更像是标签\t分隔,因此您应该在从文件中读取时指定。

    reader = csv.reader(f, delimiter="\t")

然后它会正确识别您的数据,并且不会添加任何奇怪的[]。 (;

然而,如果csv的每一行直接对应于列表框的每一行,那么只需使用.curselection来获取所选行并使用enumerate来保持行数:

def removeitem():
    fr = open('Bmi.csv', 'r')
    removed_lines = listbox.curselection()
    #  ^ just get line numbers with ^ this
    lines = fr.readlines()
    fr.close()
    fr = open("Bmi.csv","w")
   # ^ you use the variable fr here but f below...
    for i,line in enumerate(lines):
        if i not in removed_lines:
             # ^ use in operator since removed_lines is a tuple
             # it is worth noting that this has the advantage of working if multiple lines are selected
            f.write(line)
          # ^ this is f but the file is fr
          #I'm pretty sure this one is a typo
    listbox.delete(ANCHOR)
    # ^ this may not work if multiple lines are selected
    fr.close()