Учитывая следующий файл csv:
01;blue;brown;black
02;glass;rock;paper
03;pigeon;squirel;shark
Моя цель - заменить (уникальную) строку, содержащую «02» в 1-й позиции.
Я написал этот фрагмент кода:
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 в другом виде не кажется самым эффективным способом, особенно для больших файлов:
- Как только совпадение найдено, мы продолжаем читать до конца.
- Мы должны переписать каждую строку одну за другой.
- Запись второго файла не очень практична и неэффективна для хранения.
Я написал второй фрагмент кода, который, кажется, отвечает на эти две проблемы:
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)
Согласны ли вы, что второе решение более эффективно? Есть ли у вас какие-либо улучшения или лучший способ продолжить?
РЕДАКТИРОВАНИЕ: количество символов в строке может варьироваться.
EDIT 2: я, по-видимому, обязан прочитать и переписать все, если я не хочу использовать отступы. Возможным решением было бы решение, подобное базе данных, я рассмотрю его в будущем.
Если бы мне пришлось выбирать между этими двумя решениями, какое из них было бы лучшим с точки зрения производительности?
seek
, а затем перезаписать только эту строку, дополнив ее, например, пространство, чтобы получить старую длину, если старая строка не слишком короткая, тогда вам также придется перезаписать все следующие строки в файле (пока вы не найдете другую строку, которая была дополнена ранее, и вы можете удалить это дополнение). - person tobias_k   schedule 28.02.2019