добавить новую строку в старый CSV-файл Python - PullRequest
159 голосов
/ 02 марта 2010

Я пытаюсь добавить новую строку в мой старый CSV-файл. По сути, он обновляется каждый раз, когда я запускаю скрипт Python.

Сейчас я сохраняю старые значения строк csv в списке, а затем удаляю файл csv и снова создаю его с новым значением списка.

Хотелось бы узнать, есть ли лучшие способы сделать это.

Ответы [ 6 ]

200 голосов
/ 02 марта 2010
with open('document.csv','a') as fd:
    fd.write(myCsvRow)

Открытие файла с параметром 'a' позволяет добавить его в конец файла вместо простой перезаписи существующего содержимого. Попробуйте это.

113 голосов
/ 06 июня 2016

Я предпочитаю это решение, используя модуль csv из стандартной библиотеки и оператор with, чтобы не оставлять файл открытым.

Ключевым моментом является использование 'a' для добавления при открытии файла.

import csv   
fields=['first','second','third']
with open(r'name', 'a') as f:
    writer = csv.writer(f)
    writer.writerow(fields)

Если вы используете Python 2.7, у вас могут появиться лишние новые строки в Windows. Вы можете попытаться избежать их, используя 'ab' вместо 'a', однако это приведет к тому, что вы TypeError: требуется байтоподобный объект, а не 'str' в Python и CSV в Python 3.6, в то время как добавление newline='', как сказала Наташа в Python 3.6, приведет к проблемам с совместимостью в текстовом / двоичном режиме модуля *1018* Python 2 и 3.

15 голосов
/ 21 июня 2018

Основываясь на ответе @G M и обращая внимание на предупреждение @John La Rooy, я смог добавить новую строку, открывающую файл в режиме 'a'.

Даже в Windows, чтобы избежать проблемы перевода строки, вы должны объявить его как newline=''.

Теперь вы можете открыть файл в режиме 'a' (без буквы b).

import csv

with open(r'names.csv', 'a', newline='') as csvfile:
    fieldnames = ['This','aNew']
    writer = csv.DictWriter(csvfile, fieldnames=fieldnames)

    writer.writerow({'This':'is', 'aNew':'Row'})

Я не пробовал с обычным писателем (без Dict), но я думаю, что это тоже будет хорошо.

12 голосов
/ 02 марта 2010

Вы открываете файл в режиме 'a' вместо 'w'?

См. Чтение и запись файлов в документации по Python

7,2. Чтение и запись файлов

open () возвращает объект файла и чаще всего используется с двумя аргументами: open (имя файла, режим).

>>> f = open('workfile', 'w')
>>> print f <open file 'workfile', mode 'w' at 80a0960>

Первый аргумент - это строка, содержащая имя файла. Второй аргумент другая строка, содержащая несколько символов, описывающих, каким образом файл будет использован. режим может быть 'r', когда файл будет только читать, 'w' только для записи (существующий файл с тем же именем будет стереть), и «а» открывает файл для добавления; любые данные, записанные в файл автоматически добавляется в конец. 'r +' открывает файл для и чтение и письмо. Аргумент mode является необязательным; г будет предполагается, если оно опущено.

В Windows добавленный в режим «b» открывает файл в двоичном режиме, поэтому Есть также такие режимы, как 'rb', 'wb' и 'r + b'. Python на Windows делает различие между текстовыми и двоичными файлами; конец строки символы в текстовых файлах автоматически немного изменяются, когда данные читается или пишется. Это закулисное изменение данных файла подходит для текстовых файлов ASCII, но он может испортить двоичные данные в файлах JPEG или EXE. Будьте очень осторожны, чтобы использовать двоичный режим при чтении и писать такие файлы. В Unix не помешает добавить 'b' к режим, так что вы можете использовать его независимо от платформы для всех двоичных файлов файлы.

4 голосов
/ 06 февраля 2019

Если файл существует и содержит данные, то можно автоматически сгенерировать параметр fieldname для csv.DictWriter:

# read header automatically
with open(myFile, "r") as f:
    reader = csv.reader(f)
    for header in reader:
        break

# add row to CSV file
with open(myFile, "a", newline='') as f:
    writer = csv.DictWriter(f, fieldnames=header)
    writer.writerow(myDict)
4 голосов
/ 15 марта 2018
# I like using the codecs opening in a with 
field_names = ['latitude', 'longitude', 'date', 'user', 'text']
with codecs.open(filename,"ab", encoding='utf-8') as logfile:
    logger = csv.DictWriter(logfile, fieldnames=field_names)
    logger.writeheader()

# some more code stuff 

    for video in aList:
        video_result = {}                                     
        video_result['date'] = video['snippet']['publishedAt']
        video_result['user'] = video['id']
        video_result['text'] = video['snippet']['description'].encode('utf8')
        logger.writerow(video_result) 
...