给定以下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)
你同意第二种解决方案更有效吗?你有什么改进或更好的方法吗?
行中的字符数可以变化。
如果我不想使用填充,我显然有义务阅读和重写所有内容。一个可能的解决方案是一个类似数据库的解决方案,我将在未来考虑它。
如果我必须在这两种解决方案中做出选择,哪一种是性能最好的?
1条答案
按热度按时间d6kp6zgx1#
由于行中的字符可能会有所不同,我要么读/写整个文件,要么;正如@tobias_k所说,使用seek()返回到行的开头:
我想避免使用填充,所以我使用time.perf_counter()来测量两个代码的执行时间,秒的解决方案似乎快了(几乎快了2)(CSV为10000行,匹配第6000行)。
一种替代方法是迁移到关系数据库*。