覆盖CSV文件中特定行的最有效方法

4ktjp1zp  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(97)

给定以下csv文件:

01;blue;brown;black
02;glass;rock;paper
03;pigeon;squirel;shark

我的目标是替换第一个位置中包含'02'的(唯一)行。
我写了这段代码:

with open("csv", 'r+', newline='', encoding='utf-8') as csvfile, open('csvout', 'w', newline='', encoding='utf-8') as out:
    reader = csv.reader(csvfile, delimiter=';')
    writer = csv.writer(out, delimiter=';')
    for row in reader:
        if row[0] != '02':
            writer.writerow(row)
        else:
            writer.writerow(['02', 'A', 'B', 'C'])

但是在另一个文件中重写整个CSV似乎不是最有效的方法,特别是对于大文件:
1.一旦找到匹配项,我们就继续读到最后。
1.我们得一行一行地重写。
1.写入第二个文件既不实用,也没有存储效率。
我写了第二段代码,似乎可以回答这两个问题:

with open("csv", 'r+', newline='', encoding='utf-8') as csvfile:
    content = csvfile.readlines()
    for index, row in enumerate(content):
        row = row.split(';')
        if row[2] == 'rock':
            tochange = index
            break
    content.pop(tochange)
    content.insert(tochange, '02;A;B;C\n')
    content = "".join(content)
    csvfile.seek(0)
    csvfile.truncate(0)     # Erase content
    csvfile.write(content)

你同意第二种解决方案更有效吗?你有什么改进或更好的方法吗?
行中的字符数可以变化。
如果我不想使用填充,我显然有义务阅读和重写所有内容。一个可能的解决方案是一个类似数据库的解决方案,我将在未来考虑它。
如果我必须在这两种解决方案中做出选择,哪一种是性能最好的?

d6kp6zgx

d6kp6zgx1#

由于行中的字符可能会有所不同,我要么读/写整个文件,要么;正如@tobias_k所说,使用seek()返回到行的开头:

  • 如果行较短,只写行,并用空格填充;
  • 如果长度相同,则只写一行;
  • 如果它更长,重写该行和以下内容。

我想避免使用填充,所以我使用time.perf_counter()来测量两个代码的执行时间,秒的解决方案似乎快了(几乎快了2(CSV为10000行,匹配第6000行)。
一种替代方法是迁移到
关系数据库
*。

相关问题