Utwórz plik .csv z wartościami z listy w języku Python

182

Próbuję utworzyć plik .csv z wartościami z listy w języku Python. Kiedy wypisuję wartości na liście, wszystkie są w formacie Unicode (?), Czyli wyglądają mniej więcej tak

[u'value 1', u'value 2', ...]

Jeśli iteruję przez wartości na liście, tj for v in mylist: print v. Wydają się być zwykłym tekstem.

I mogę umieścić ,między każdym zprint ','.join(mylist)

I mogę wyprowadzić do pliku, tj

myfile = open(...)
print >>myfile, ','.join(mylist)

Ale chcę wyprowadzać do pliku CSV i mieć ograniczniki wokół wartości na liście, np

"value 1", "value 2", ... 

Nie mogę znaleźć prostego sposobu na umieszczenie separatorów w formatowaniu, np. Próbowałem użyć joininstrukcji. W jaki sposób mogę to zrobić?

Fortilan
źródło
Dziękuję wszystkim, połączyłem pomysły z kilku odpowiedzi, aby rozwiązać moje pytanie :) Teraz używam modułu csv do zapisywania danych [...] bezpośrednio do pliku import csv data = [...] myfile = open ( ..., 'wb') out = csv.writer (open ("myfile.csv", "w"), delimiter = ',', quoting = csv.QUOTE_ALL) out.writerow (data) działa dobrze, konstruuję moje dane [], pobierając niektóre dane z arkusza kalkulacyjnego za pomocą xlrd, a moduł csv zapisuje je do pliku z odpowiednimi ogranicznikami, wszystko w porządku :) ty znowu
Fortilan
Nowszym podejściem może być użycie pand
Richard
Użytkownicy Pythona 3.4, to działało najlepiej dla mnie: stackoverflow.com/questions/25022677/…
Leigh

Odpowiedzi:

254
import csv

with open(..., 'wb') as myfile:
    wr = csv.writer(myfile, quoting=csv.QUOTE_ALL)
    wr.writerow(mylist)

Edycja: działa tylko z Pythonem 2.x.

Aby pracować z Pythona 3.x wymiany wbz w( zobacz ten SO odpowiedź )

with open(..., 'w', newline='') as myfile:
     wr = csv.writer(myfile, quoting=csv.QUOTE_ALL)
     wr.writerow(mylist)
Alex Martelli
źródło
11
Zwróć uwagę, że csvmoduł w 2.x nie radzi sobie poprawnie z unikodami; przykłady, jak sobie z tym poradzić, znajdziesz w dokumentacji modułu. docs.python.org/library/csv.html
Ignacio Vazquez-Abrams,
14
możesz również użyć wr.writerows (lista)
tovmeod
4
Wydaje się, że programy Writerows dzielą każdy element listy na kolumny, jeśli każdy element jest również listą. Jest to bardzo przydatne do tworzenia tabel.
whatnick
6
To nie działa z Pythonem 3.4. Dostaję TypeError: 'str' does not support the buffer interface.
botchniaque
1
W przypadku Pythona 2 użyj 'w'tutaj: stackoverflow.com/questions/34283178/…
banan3'14
106

Oto bezpieczna wersja aplikacji Alexa Martellego:

import csv

with open('filename', 'wb') as myfile:
    wr = csv.writer(myfile, quoting=csv.QUOTE_ALL)
    wr.writerow(mylist)
Cristian Garcia
źródło
3
plus 1 za użycie with, upewniając się, że plik jest zamknięty po zakończeniu
BoltzmannBrain
Jeśli używam tego wewnątrz pętli for, czy cały blok with powinien być zagnieżdżony w pętli for? A może bardziej efektywne byłoby posiadanie tylko wr.writerow(my_list)wewnątrz pętli?
crypdick,
1
@crypdick zdecydowanie nie powinieneś umieszczać całego bloku w pętli. Otwórz plik, a następnie zapisz każdy wiersz w pętli. Nie ma potrzeby otwierania pliku n razy, aby zapisać n wierszy.
Greg Kaleka
Jeśli piszesz obiekty typu string do pliku, sugerujemy użycie 'wt' podczas otwierania pliku, aby uniknąć TypeError: wymagany jest obiekt podobny do bajtów, a nie 'str'.
don_Gunner94
41

Na innym podejściu, można użyć DataFrame w pand : A może to łatwo zrzucić danych do pliku CSV, podobnie jak poniższy kod:

import pandas
df = pandas.DataFrame(data={"col1": list_1, "col2": list_2})
df.to_csv("./file.csv", sep=',',index=False)
Qy Zuo
źródło
1
Dziękujemy za ten fragment kodu, który może zapewnić natychmiastową pomoc. Właściwe wyjaśnienie znacznie poprawiłoby jego wartość edukacyjną, pokazując, dlaczego jest to dobre rozwiązanie problemu, i uczyniłoby go bardziej użytecznym dla przyszłych czytelników z podobnymi, ale nie identycznymi pytaniami. Proszę edytować swoje odpowiedzi, aby dodać wyjaśnienie, i dać wskazówkę co zastosować ograniczenia i założenia.
Toby Speight,
5
Aby to zadziałało, listy muszą mieć tę samą długość, w przeciwnym razie otrzymasz ValueError (pandy v 0.22.0)
cheevahagadog
32

Najlepsza opcja, jaką znalazłem, to użycie savetxtz numpymodułu :

import numpy as np
np.savetxt("file_name.csv", data1, delimiter=",", fmt='%s', header=header)

W przypadku, gdy masz wiele list, które muszą być ułożone w stos

np.savetxt("file_name.csv", np.column_stack((data1, data2)), delimiter=",", fmt='%s', header=header)
tokenizer_fsj
źródło
8
Jest to dobre do prac numerycznych, ale nie zadziała, gdy na liście znajdują się ciągi znaków.
Ricardo Cruz
12

Użyj csvmodułu Pythona do czytania i pisania plików rozdzielanych przecinkami lub tabulatorami. Preferowany jest moduł csv, ponieważ zapewnia dobrą kontrolę nad kwotowaniami.

Na przykład, oto przykład pracy dla Ciebie:

import csv
data = ["value %d" % i for i in range(1,4)]

out = csv.writer(open("myfile.csv","w"), delimiter=',',quoting=csv.QUOTE_ALL)
out.writerow(data)

Produkuje:

"value 1","value 2","value 3"
vy32
źródło
4
Tworzy dla mnie pusty plik
caspii
Pierwsze uruchomienie jest puste i nie możesz go wtedy usunąć, ponieważ jest następnie otwierany w Pythonie. Drugie uruchomienie (lub dokładniej: out = csv.writer(open("myfile.csv","w"), delimiter=',',quoting=csv.QUOTE_ALL))wypełnia dane, bez względu na to, czy umieścisz, open("myfile.csv","w")czy nowy plik open("myfile2.csv","w"). Wydaje się, że obiekt wyjściowy nie może poradzić sobie z obiektem pliku zbudowanym podczas wykonywania, ale przechowuje proces wyjściowy jako zadanie do wykonania. Innymi słowy: obiekt out przechowuje obiekt pliku w pierwszym uruchomieniu, ale zapisuje tylko wtedy, gdy obiekt pliku już istnieje! Zobacz odpowiednie rozwiązanie poniżej @Saurabh Adhikary
Lorenz
7

W tym przypadku możesz użyć metody string.join.

Podziel na kilka wierszy dla większej przejrzystości - oto sesja interaktywna

>>> a = ['a','b','c']
>>> first = '", "'.join(a)
>>> second = '"%s"' % first
>>> print second
"a", "b", "c"

Lub jako pojedyncza linia

>>> print ('"%s"') % '", "'.join(a)
"a", "b", "c"

Jednak możesz mieć problem z tym, że twoje ciągi znaków mają osadzone cudzysłowy. Jeśli tak jest, musisz zdecydować, jak przed nimi uciec.

Moduł CSV może dbać o to wszystko dla ciebie, co pozwala na wybór pomiędzy różnymi opcjami cytując (wszystkie pola, pola tylko z cytatami i separatory, tylko non pól numerycznych, etc) i jak charecters kontroli Esacpe (cudzysłów, lub uciekające ciągi). Jeśli twoje wartości są proste, string.join prawdopodobnie będzie OK, ale jeśli musisz zarządzać wieloma przypadkami brzegowymi, użyj dostępnego modułu.

Robert Christie
źródło
3

To rozwiązanie brzmi szalenie, ale działa gładko jak miód

import csv

with open('filename', 'wb') as myfile:
    wr = csv.writer(myfile, quoting=csv.QUOTE_ALL,delimiter='\n')
    wr.writerow(mylist)

Plik jest zapisywany przez csvwriter, dlatego właściwości csv są zachowane, tj. Oddzielone przecinkami. Separator pomaga w głównej części, za każdym razem przenosząc elementy listy do następnego wiersza.

Saurabh Adhikary
źródło
1
Tak mały i taki szybki
Ian Samz
1
działa, a jeśli masz zagnieżdżoną listę, rozszerzającą przykład @ vy32, masz:data = [["value %d" % i, "value %d" % (i+1)] for i in range(1,4)] with open("myfile.txt","w") as f: out = csv.writer(f, quoting=csv.QUOTE_ALL, delimiter='\n') out.writerow([';'.join(x) for x in data])
Lorenz
czy to naprawdę brzmi szalenie? Myślę, że to brzmi doskonale
Stephanie Owen
3

Tworzenie i zapisywanie w pliku CSV

Poniższy przykład demonstruje tworzenie i pisanie pliku csv. aby utworzyć dynamiczny program do zapisywania plików, musimy zaimportować pakiet import csv , a następnie utworzyć wystąpienie pliku z odniesieniem do pliku Np .: - z otwartym ("D: \ sample.csv", "w", newline = "" ) jako autor_pliku

tutaj jeśli plik nie istnieje we wspomnianym katalogu plików, to python utworzy ten sam plik w określonym katalogu, a „w” reprezentuje zapis, jeśli chcesz odczytać plik, zamień „w” na „r” lub dopisz do istniejącego pliku, a następnie „a”. newline = "" określa, że ​​usuwa dodatkowy pusty wiersz za każdym razem, gdy tworzysz wiersz, więc aby wyeliminować pusty wiersz, używamy newline = "", tworzymy niektóre nazwy pól (nazwy kolumn), używając list takich jak fields = ["Names", "Age "," Class "] , a następnie zastosuj do instancji pisarza, takiej jak writer = csv.DictWriter (file_writer, fieldnames = fields) tutaj, używając edytora Dictionary i przypisując nazwy kolumn, aby zapisać nazwy kolumn w csv, używamy writer. , podczas gdy wartości pliku muszą być przekazywane przy użyciu metody słownikowej, tutaj kluczem jest nazwa kolumny, a wartość to odpowiednia wartość klucza

import csv 

with open("D:\\sample.csv","w",newline="") as file_writer:

   fields=["Names","Age","Class"]

   writer=csv.DictWriter(file_writer,fieldnames=fields)

   writer.writeheader()

   writer.writerow({"Names":"John","Age":21,"Class":"12A"})
prasanna kumar
źródło
2

Notatnik Jupyter

Powiedzmy, że Twoja lista jest A

Następnie możesz zakodować następującą reklamę, którą będziesz mieć jako plik csv (tylko kolumny!)

R="\n".join(A)
f = open('Columns.csv','w')
f.write(R)
f.close()
rsc05
źródło
1

na pewno powinieneś użyć modułu CSV, ale są szanse, że musisz napisać Unicode. Dla tych, którzy muszą pisać unicode, oto klasa z przykładowej strony, której możesz użyć jako modułu util:

import csv, codecs, cStringIO

class UTF8Recoder:
    """
    Iterator that reads an encoded stream and reencodes the input to UTF-8
    """
    def __init__(self, f, encoding):
        self.reader = codecs.getreader(encoding)(f)

def __iter__(self):
    return self

def next(self):
    return self.reader.next().encode("utf-8")

class UnicodeReader:
    """
    A CSV reader which will iterate over lines in the CSV file "f",
    which is encoded in the given encoding.
    """

def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds):
    f = UTF8Recoder(f, encoding)
    self.reader = csv.reader(f, dialect=dialect, **kwds)

def next(self):
    row = self.reader.next()
    return [unicode(s, "utf-8") for s in row]

def __iter__(self):
    return self

class UnicodeWriter:
    """
    A CSV writer which will write rows to CSV file "f",
    which is encoded in the given encoding.
"""

def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds):
    # Redirect output to a queue
    self.queue = cStringIO.StringIO()
    self.writer = csv.writer(self.queue, dialect=dialect, **kwds)
    self.stream = f
    self.encoder = codecs.getincrementalencoder(encoding)()

def writerow(self, row):
    self.writer.writerow([s.encode("utf-8") for s in row])
    # Fetch UTF-8 output from the queue ...
    data = self.queue.getvalue()
    data = data.decode("utf-8")
    # ... and reencode it into the target encoding
    data = self.encoder.encode(data)
    # write to the target stream
    self.stream.write(data)
    # empty queue
    self.queue.truncate(0)

def writerows(self, rows):
    for row in rows:
        self.writerow(row)
kommradHomer
źródło
1

Oto kolejne rozwiązanie, które nie wymaga csvmodułu.

print ', '.join(['"'+i+'"' for i in myList])

Przykład:

>>> myList = [u'value 1', u'value 2', u'value 3']
>>> print ', '.join(['"'+i+'"' for i in myList])
"value 1", "value 2", "value 3"

Jeśli jednak początkowa lista zawiera jakieś ", nie zostaną one zastąpione. Jeśli jest to wymagane, można wywołać funkcję, aby zmienić jej znaczenie w następujący sposób:

print ', '.join(['"'+myFunction(i)+'"' for i in myList])
Richard
źródło