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

Python 从列表框中的选定行删除Csv文件中的行,python,csv,tkinter,listbox,Python,Csv,Tkinter,Listbox,我有一个小界面,它有一个列表框,其中包含bmi.csv文件中的文本行。我知道如何从列表框中删除该行,但不知道如何从csv文件中删除该行 我在这里用这个代码导入csv数据 with open('Bmi.csv', newline='') as f: reader = csv.reader(f) for row in reader: listbox.insert(END, row) fr.close() 这是我的按钮,用于调用删除项功能 mbutton =

我有一个小界面,它有一个列表框,其中包含bmi.csv文件中的文本行。我知道如何从列表框中删除该行,但不知道如何从csv文件中删除该行

我在这里用这个代码导入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()
这是我的删除项函数

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()

我试图在linebox中获取所选行的字符串,然后在csv文件中搜索该字符串,然后将其删除,但我听说在执行此操作时需要重新创建csv。如何执行此操作?

即使您的文件为csv格式,但仍使用基本文本格式,由于您只在
列表框中显示文本
,因此根本不需要包含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
默认情况下假定数据以逗号分隔,但查看您提供的屏幕截图,您的数据看起来更像是tab
\t
分隔的,因此,在从文件读取时,应该指定

    reader = csv.reader(f, delimiter="\t")
然后它将正确识别您的数据,并且不会添加任何奇怪的
[]
。(

但是,如果csv的每一行都直接对应于列表框的每一行,那么使用
.curselection
获取所选行,并使用
枚举
保留行计数,会更容易:

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()

我认为您只需要保持与打开文件的方式一致,因为这是您第一次指定
newline=“”
但在
removietem
中,您不需要这样做,因为行不会表示相同的数据。除此之外,我认为您拥有的代码可以正常工作。如果仍然不起作用,您可以尝试实现reader和writer对象:
lines=list(csv.reader(fr))
write=csv.writer(fr);对于行中的行:if line!=value:write.writerow(line)
我刚刚尝试了这个方法,很好,它删除了行,但在行前后保留了“[]”,因此当我删除2项时,它有[]在每一行的3行中,在它以前的位置哦,亲爱的,我刚刚意识到你正在覆盖原始文件,你是否可能在测试时弄乱了原始数据?(我希望你有备份)我不介意任何原始数据,因为当它完成时,我将空白地提交给我的讲师,因此他在中添加的任何数据都将是唯一显示的数据。非常感谢你,我必须一遍又一遍地查看我的代码,甚至没有注意到“f”而不是fr。非常感谢Tadhg!