读写同一个csv文件删除行如果条件满足(停止writerow删除文件中的所有内容)

2024-03-29 13:14:51 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试创建一个存档,以存储系统中可用书籍的列表。我希望我的程序要求用户输入csv文件,从该文件中读取书籍列表,检查出版年份,如果该书超过7年,则删除该行。 我想把所有的东西都放在一个文件里。在

到目前为止,writerow没有删除某些行,而是删除文件中的所有内容。有人能帮我弄明白怎么修吗?在

import csv
import os
import time

archive = os.listdir()


def get_user_files(self):
    while True:
        for position, file_name in enumerate(archive):
            print(position, "-", file_name)
        userInput = input("\n\n ")
        if (int(userInput) < 0) or (int(userInput) > len(archive)):
            print("Invalid Input. Try again. \n")
        else:
            print("Loading succesful!")
            break

    global cvs_list
    cvs_list = archive[int(userInput)]  # Store file
    archive.remove(cvs_list)  # Remove from the list


    with open(cvs_list, 'r') as in_file, open(cvs_list, 'w') as out_file:
        reader = csv.reader(in_file)
        writer = csv.writer(out_file)
        for row in reader:
            next(reader) #skip headers
            if int(row[2]) < 2011:
                writer.writerow(row)

编辑:

^{pr2}$

Tags: 文件csvinimportlistreaderfileint
3条回答
import csv

def filter_dates(csv_filepath)
    with open(csv_filepath, 'r') as in_file:
        csv_in = list(csv.reader(in_file))
    # create accumulator for new list to add only valid values
    filtered_list = []
    filetered_list.append(csv_in[0]) # append header to new list
    # filter the list making sure no errors appear BEFORE writing to the file
    for row in csv_in[1:]: #skip header (first row)
        if int(row[2]) >= 2011: # if entry is NEWER OR EQUAL TO than 7 years, we add it to filtered_list
            filtered_list.append(row)
    # now filtered_list contains only entires where index position 2 contains valid years
    with open(csv_filepath, 'w') as out_file:
        writer = csv.writer(out_file)
        writer.writerows

下面是一个完全独立的例子:

^{pr2}$

注意:

  • 通常,在打开要写入的文件(在本例中是覆盖)之前,最好将这类内容存储在内存中,这样在读取和过滤文件时出现的任何错误都会在我们试图修改输出之前发生
  • 覆盖一个文件最简单的方法是首先读取它,将内容提交到内存中(csv_in我在第一个with块中定义的数组),然后*最后8一旦数据准备就绪(filtered_list)提交到一个文件
  • 永远不要在python中使用global声明,这是不值得的,并且会引起很多麻烦

试验

由于这样的原因,通常不建议读写同一个打开的文件句柄。相反,将整个文件读到一个数据结构,并在一个单独的with块中写入新数据。这也使得写另一个文件变得更容易(也许附加了时间戳),当你(像所有人一样)不可避免地把事情搞砸,需要在旧数据上尝试新代码时,这会很方便——你有备份。在

你有:

with open(cvs_list, 'r') as in_file:
        csv_in = csv.reader(in_file, quoting=csv.QUOTE_ALL)
        filtered_list = []
        row1 = next(csv_in)
        filtered_list.append(row1)
        for row in csv_in:
            if int(row[2]) >= 2011: 
                row.append(filtered_list)
        # WRONG! you are opening the same file for output 
        # in the upper block
        with open(cvs_list, 'w') as out_file:
            writer = csv.writer(out_file)
            writer.writerows(filtered_list)

同时读写tmp文件,然后将tmp文件复制到源文件上,这比要好得多。在

像这样:

^{pr2}$

然后在with块的末尾,您可以将临时文件复制到源文件的顶部:

from shutil import move
move(tmp_file, cvs_list)

相关问题 更多 >