dołącz nowy wiersz do starego pythonowego pliku csv

207

Próbuję dodać nowy wiersz do mojego starego pliku csv. Zasadniczo jest aktualizowany za każdym razem, gdy uruchamiam skrypt Python.

Obecnie przechowuję stare wartości wierszy csv na liście, a następnie usuwam plik csv i tworzę go ponownie z nową wartością listy.

Chciałbym wiedzieć, czy są na to lepsze sposoby.

laspal
źródło

Odpowiedzi:

246
with open('document.csv','a') as fd:
    fd.write(myCsvRow)

Otwarcie pliku z 'a'parametrem umożliwia dołączenie na końcu pliku zamiast zwykłego zastąpienia istniejącej zawartości. Spróbuj tego.

inkedmn
źródło
2
Próbowałem fp = open (csv_filepathwithname, 'wa') writer = csv.writer (fp) somelist = [3,56,3,6,56] writer.writerow ((somelist)), ale dołączany jest tylko ostatni wiersz plik.
laspal
Metoda zakłada, że ​​dołączane elementy są oddzielone przecinkami, co nie zawsze musi mieć miejsce. Wtedy metoda zapisu nie utrzyma ogranicznika csv. Poniższa odpowiedź jest bardziej solidna w tym sensie.
sheth7
152

Wolę to rozwiązanie, używając csvmodułu ze standardowej biblioteki i withinstrukcji, aby uniknąć pozostawienia pliku otwartego.

Kluczowym punktem jest 'a'dołączanie przy otwieraniu pliku.

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

Jeśli używasz języka Python 2.7, możesz napotkać zbędne nowe linie w systemie Windows. Możesz spróbować uniknąć ich użycia 'ab'zamiast 'a'tego, jednak spowoduje to TypError: wymagany jest obiekt podobny do bajtów, a nie „str” w Pythonie i CSV w Pythonie 3.6. Dodanie newline='', jak sugeruje Natacha, spowoduje wsteczną niezgodność między Pythonem 2 i 3 .

GM
źródło
24

Opierając się na odpowiedzi @GM i zwracając uwagę na ostrzeżenie @John La Rooy, mogłem dołączyć nowy wiersz otwierający plik w 'a'trybie.

Nawet w systemie Windows, aby uniknąć problemu z nową linią, musisz go zadeklarować jako newline=''.

Teraz możesz otworzyć plik w 'a'trybie (bez 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'})

Nie próbowałem ze zwykłym pisarzem (bez Dict), ale myślę, że też będzie dobrze.

Natacha
źródło
12

Czy otwierasz plik w trybie „a” zamiast „w”?

Zobacz Odczytywanie i zapisywanie plików w dokumentach Pythona

7.2 Odczytywanie i zapisywanie plików

open () zwraca obiekt pliku i jest najczęściej używany z dwoma argumentami: open (nazwa pliku, tryb).

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

Pierwszy argument to ciąg zawierający nazwę pliku. Drugi argument to kolejny ciąg zawierający kilka znaków opisujących sposób użycia pliku. trybem może być „r”, gdy plik będzie tylko odczytywany, „w” tylko do zapisu (istniejący plik o tej samej nazwie zostanie usunięty), a „a” otwiera plik do dołączenia; wszelkie dane zapisane do pliku są automatycznie dodawane na końcu. „r +” otwiera plik do odczytu i zapisu. Argument trybu jest opcjonalny; „r” zostanie przyjęte, jeśli zostanie pominięte.

W systemie Windows „b” dołączony do trybu otwiera plik w trybie binarnym, więc istnieją również tryby takie jak „rb”, „wb” i „r + b”. Python w systemie Windows rozróżnia pliki tekstowe i binarne; znaki końca wiersza w plikach tekstowych są automatycznie nieznacznie zmieniane podczas odczytu lub zapisu danych. Ta zakulisowa modyfikacja danych pliku jest odpowiednia dla plików tekstowych ASCII, ale spowoduje uszkodzenie takich danych binarnych w plikach JPEG lub EXE. Podczas odczytu i zapisu takich plików należy bardzo uważać na tryb binarny. W systemie Unix dodanie „b” do trybu nie boli, więc możesz używać go niezależnie od platformy dla wszystkich plików binarnych.

John La Rooy
źródło
być może możesz uszczegółowić swoją odpowiedź, to wyglądałaby jak prawdziwa odpowiedź :-)
user702846
@ użytkownik, dodałem link - czy to ci pomaga?
John La Rooy,
7

Jeśli plik istnieje i zawiera dane, możliwe jest automatyczne wygenerowanie fieldnameparametru dla 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)
Ron Kalian
źródło
6
# 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) 
markkaufman
źródło
1
Popraw wcięcie. Odpowiedzi również korzystają z wyjaśnień - i te odpowiedzi również przyciągają więcej głosów pozytywnych.
Pan T
To jest prosty kod, otwiera plik w trybie dołączania, wypisuje nagłówek rec, a następnie przegląda rekordy wideo na liście.
markkaufman
2

Robię w ten sposób, aby dodać nową linię do pliku .csv:

pose_x = 1 
pose_y = 2

with open('path-to-your-csv-file.csv', mode='a') as file_:
    file_.write("{},{}".format(pose_x, pose_y))
    file_.write("\n")
Benyamin Jafari
źródło