Crea un file .csv con valori da un elenco Python


181

Sto cercando di creare un file .csv con i valori da un elenco Python. Quando stampo i valori nell'elenco sono tutti unicode (?), Cioè hanno un aspetto simile a questo

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

Se eseguo l'iterazione attraverso i valori nell'elenco, ad esempio for v in mylist: print v, sembrano essere testo semplice.

E posso mettere un ,tra ciascuno conprint ','.join(mylist)

E posso produrre un file, ad es

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

Ma voglio produrre un CSV e avere delimitatori attorno ai valori nell'elenco, ad es

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

Non riesco a trovare un modo semplice per includere i delimitatori nella formattazione, ad esempio ho provato attraverso l' joinistruzione. Come posso fare questo?


Grazie a tutti, ho combinato le idee di alcune risposte per risolvere la mia domanda :) Ora uso il modulo csv per scrivere [...] i dati direttamente in un file import csv data = [...] myfile = open ( ..., 'wb') out = csv.writer (open ("myfile.csv", "w"), delimiter = ',', quoting = csv.QUOTE_ALL) out.writerow (data) funziona bene, costruisco i miei dati [] estraendo alcuni dati da un foglio di calcolo usando xlrd e il modulo CSV li scrive in un file con i delimitatori giusti tutti bene :) ty all again
Fortilan

Un approccio più recente potrebbe essere l'uso dei panda
Richard,

Utenti Python 3.4, questo ha funzionato meglio per me: stackoverflow.com/questions/25022677/…
Leigh

Risposte:


252
import csv

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

Modifica: funziona solo con Python 2.x.

Per farlo funzionare con Python 3.x sostituisci wbcon w( vedi questa risposta SO )

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

11
Si noti che il csvmodulo in 2.x non gestisce correttamente gli Unicode; consultare la documentazione del modulo per esempi su come gestirlo. docs.python.org/library/csv.html
Ignacio Vazquez-Abrams,

14
puoi anche usare wr.writerows (elenco)
tovmeod il

4
Gli scrittori sembrano suddividere ogni elemento dell'elenco in colonne se ogni elemento è anche un elenco. Questo è abbastanza utile per produrre tabelle.
whatnick

6
Questo non funziona con Python 3.4. Sto ottenendo TypeError: 'str' does not support the buffer interface.
botchniaque,

1
Per Python 2, utilizzare 'w'come qui: stackoverflow.com/questions/34283178/…
banan3'14

105

Ecco una versione sicura di Alex Martelli:

import csv

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

3
più 1 per l'utilizzo with, assicurandoti che il file sia chiuso al termine
BoltzmannBrain,

Se lo sto usando all'interno di un ciclo for, l'intero con blocco dovrebbe essere nidificato sotto il ciclo for? O sarebbe più efficiente avere solo wr.writerow(my_list)all'interno del loop?
Crypdick,

1
@crypdick non dovresti assolutamente mettere l'intero blocco nel loop. Apri il file, quindi scrivi ogni riga in un ciclo. Non è necessario aprire il file n volte per scrivere n righe.
Greg Kaleka,

Se stai scrivendo oggetti stringa in un file, suggeriresti di usare 'wt' durante l'apertura del file per evitare TypeError: è richiesto un oggetto simile a byte, non 'str'.
don_Gunner94

41

Per un altro approccio, è possibile utilizzare dataframe in panda : E può facilmente scaricare i dati in formato CSV, proprio come il codice qui sotto:

import pandas
df = pandas.DataFrame(data={"col1": list_1, "col2": list_2})
df.to_csv("./file.csv", sep=',',index=False)

1
Grazie per questo frammento di codice, che può fornire un aiuto immediato. Una spiegazione adeguata migliorerebbe notevolmente il suo valore educativo mostrando perché questa è una buona soluzione al problema e la renderebbe più utile ai futuri lettori con domande simili, ma non identiche. Si prega di modificare la risposta di aggiungere una spiegazione, e dare un'indicazione di ciò si applicano le limitazioni e le assunzioni.
Toby Speight,

5
Inoltre, per funzionare, gli elenchi devono avere la stessa lunghezza, altrimenti otterrai un ValueError (panda v 0.22.0)
cheevahagadog,

32

L'opzione migliore che ho trovato è stata usando il savetxtdal numpymodulo :

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

Nel caso in cui siano presenti più elenchi che devono essere impilati

np.savetxt("file_name.csv", np.column_stack((data1, data2)), delimiter=",", fmt='%s', header=header)

8
Questo è utile per il lavoro numerico, ma non funzionerà con le stringhe nell'elenco.
Ricardo Cruz,

12

Utilizzare il csvmodulo di Python per leggere e scrivere file delimitati da virgole o da tabulazioni. Il modulo CSV è preferito perché ti dà un buon controllo sulla quotazione.

Ad esempio, ecco l'esempio lavorato per te:

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)

produce:

"value 1","value 2","value 3"

4
Produce un file vuoto per me
caspii

La prima esecuzione è vuota e non è nemmeno possibile eliminarla, poiché viene quindi aperta in Python. Seconda esecuzione (o più precisa: out = csv.writer(open("myfile.csv","w"), delimiter=',',quoting=csv.QUOTE_ALL))riempie i dati, non importa se si inserisce open("myfile.csv","w")o un nuovo file open("myfile2.csv","w"). Sembra che l'oggetto out non sia in grado di gestire l'oggetto file creato sulla corsa, ma memorizza il processo di output come todo. In altre parole: l'oggetto out memorizza l'oggetto file alla prima esecuzione ma sta scrivendo solo quando l'oggetto file esiste già! Vedi la soluzione giusta sotto @Saurabh Adhikary
Lorenz

7

In questo caso è possibile utilizzare il metodo string.join.

Dividi alcune righe per maggiore chiarezza: ecco una sessione interattiva

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

O come linea singola

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

Tuttavia, potresti avere un problema se le tue stringhe hanno virgolette incorporate. In questo caso dovrai decidere come fuggire.

Il modulo CSV può occuparsi di tutto ciò per te, permettendoti di scegliere tra varie opzioni di quotazione (tutti i campi, solo campi con virgolette e separatori, solo campi non numerici, ecc.) E come esacpe controllare i caratteri di controllo (virgolette doppie, o stringhe di escape). Se i tuoi valori sono semplici, string.join probabilmente sarà OK ma se devi gestire molti casi limite, usa il modulo disponibile.


3

Questa soluzione sembra folle, ma funziona perfettamente come il miele

import csv

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

Il file viene scritto da csvwriter, pertanto le proprietà csv vengono mantenute, ovvero separate da virgola. Il delimitatore aiuta nella parte principale spostando le voci dell'elenco alla riga successiva, ogni volta.


1
Così piccolo e così veloce
Ian Samz il

1
funziona e se hai un elenco nidificato, espandendo l'esempio di @ vy32, hai: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

suona davvero pazzo? Penso che suona perfettamente bene
Stephanie Owen il

3

Per creare e scrivere in un file CSV

L'esempio seguente mostra come creare e scrivere un file CSV. per creare un writer di file dinamico è necessario importare un pacchetto import csv , quindi creare un'istanza del file con riferimento al file Ex: - con open ("D: \ sample.csv", "w", newline = "" ) come file_writer

qui se il file non esiste con la directory dei file menzionata, Python creerà uno stesso file nella directory specificata e "w" rappresenta la scrittura, se si desidera leggere un file, sostituire "w" con "r" o aggiungere al file esistente quindi "a". newline = "" specifica che rimuove una riga vuota in più ogni volta che crei una riga, quindi per eliminare la riga vuota usiamo newline = "", creiamo alcuni nomi di campi (nomi di colonna) usando la lista come campi = ["Nomi", "Età "," Class "] , quindi si applicano all'istanza del writer come writer = csv.DictWriter (file_writer, fieldnames = fields) qui utilizzando il writer del dizionario e assegnando i nomi delle colonne, per scrivere i nomi delle colonne in CSV utilizziamo il writer. , mentre la scrittura dei valori dei file deve essere passata utilizzando il metodo dizionario, qui la chiave è il nome della colonna e il valore è il rispettivo valore della chiave

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"})

2

Notebook Jupyter

Diciamo che la tua lista è A

Quindi puoi codificare il seguente annuncio lo avrai come file csv (solo colonne!)

R="\n".join(A)
f = open('Columns.csv','w')
f.write(R)
f.close()

1

dovresti usare sicuramente il modulo CSV, ma è probabile che tu debba scrivere unicode. Per coloro che hanno bisogno di scrivere unicode, questa è la classe dalla pagina di esempio, che puoi usare come modulo 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)

1

Ecco un'altra soluzione che non richiede il csvmodulo.

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

Esempio :

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

Tuttavia, se l'elenco iniziale ne contiene ", non verranno salvati. Se necessario, è possibile chiamare una funzione per evitarlo in questo modo:

print ', '.join(['"'+myFunction(i)+'"' for i in myList])
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.