Cree un archivo .csv con valores de una lista de Python

181

Estoy tratando de crear un archivo .csv con los valores de una lista de Python. Cuando imprimo los valores en la lista, todos son unicode (?), Es decir, se parecen a esto

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

Si repito los valores en la lista, es decir for v in mylist: print v, parecen ser texto sin formato.

Y puedo poner un ,entre cada uno conprint ','.join(mylist)

Y puedo enviar a un archivo, es decir

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

Pero quiero enviar a un CSV y tener delimitadores alrededor de los valores en la lista, por ejemplo

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

No puedo encontrar una manera fácil de incluir los delimitadores en el formato, por ejemplo, he intentado a través de la joindeclaración. ¿Cómo puedo hacer esto?

Fortilan
fuente
Gracias a todos, he combinado las ideas de algunas respuestas para resolver mi pregunta :) Ahora uso el módulo csv para escribir los datos [...] directamente en un archivo import csv data = [...] myfile = open ( ..., 'wb') out = csv.writer (open ("myfile.csv", "w"), delimiter = ',', quoting = csv.QUOTE_ALL) out.writerow (data) funciona bien, construyo mis datos [] tomando algunos datos de una hoja de cálculo usando xlrd y el módulo csv los escribe en un archivo con los delimitadores correctos todo bien :) ty all again
Fortilan
Un enfoque más reciente podría ser el uso de pandas
Richard
Python 3.4 usuarios, esto funcionó mejor para mí: stackoverflow.com/questions/25022677/…
Leigh

Respuestas:

253
import csv

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

Editar: esto solo funciona con python 2.x.

Para que funcione con python 3.x reemplace wbcon w( vea esta respuesta SO )

with open(..., 'w', newline='') as myfile:
     wr = csv.writer(myfile, quoting=csv.QUOTE_ALL)
     wr.writerow(mylist)
Alex Martelli
fuente
11
Tenga en cuenta que el csvmódulo en 2.x no trata correctamente con unicodes; Consulte la documentación del módulo para obtener ejemplos sobre cómo lidiar con esto. docs.python.org/library/csv.html
Ignacio Vazquez-Abrams
14
también puede usar wr.writerows (lista)
tovmeod
44
Writerows parece dividir cada elemento de la lista en columnas si cada elemento también es una lista. Esto es bastante útil para generar tablas.
Whatnick
66
Eso no funciona con Python 3.4. Me estoy poniendo TypeError: 'str' does not support the buffer interface.
botchniaque
1
Para Python 2, use 'w'como aquí: stackoverflow.com/questions/34283178/…
banan3'14
105

Aquí hay una versión segura de Alex Martelli:

import csv

with open('filename', 'wb') as myfile:
    wr = csv.writer(myfile, quoting=csv.QUOTE_ALL)
    wr.writerow(mylist)
Cristian Garcia
fuente
3
más 1 para usar with, asegurándose de que el archivo esté cerrado cuando termine
BoltzmannBrain
Si estoy usando esto dentro de un bucle for, ¿debería estar todo el bloque with anidado debajo del bucle for? ¿O sería más eficiente tener solo wr.writerow(my_list)dentro del bucle?
crypdick
1
@crypdick definitivamente no deberías poner todo el bloque en el bucle. Abra el archivo, luego escriba cada fila en un bucle. No es necesario abrir el archivo n veces para escribir n filas.
Greg Kaleka
Si está escribiendo objetos de cadena en un archivo, sugeriría usar 'wt' al abrir el archivo para evitar TypeError: se requiere un objeto similar a bytes, no 'str'.
don_Gunner94
41

Para otro enfoque, puede usar DataFrame en pandas : y puede volcar fácilmente los datos a csv al igual que el código a continuación:

import pandas
df = pandas.DataFrame(data={"col1": list_1, "col2": list_2})
df.to_csv("./file.csv", sep=',',index=False)
Qy Zuo
fuente
1
Gracias por este fragmento de código, que puede proporcionar ayuda inmediata. Una explicación adecuada mejoraría en gran medida su valor educativo al mostrar por qué esta es una buena solución al problema, y ​​la haría más útil para futuros lectores con preguntas similares, pero no idénticas. Por favor, editar su respuesta para agregar explicación y dar una indicación de lo que se aplican limitaciones y supuestos.
Toby Speight
55
Además, para que esto funcione, las listas deben tener la misma longitud, de lo contrario obtendrá un ValueError (pandas v 0.22.0)
cheevahagadog
32

La mejor opción que encontré fue usar savetxtdesde el numpymódulo :

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

En caso de que tenga varias listas que deben apilarse

np.savetxt("file_name.csv", np.column_stack((data1, data2)), delimiter=",", fmt='%s', header=header)
tokenizer_fsj
fuente
8
Esto es bueno para el trabajo numérico, pero no funcionará cuando aparezca cadenas en la lista.
Ricardo Cruz
12

Utilice el csvmódulo de Python para leer y escribir comas o archivos delimitados por tabuladores. Se prefiere el módulo csv porque le da un buen control sobre las citas.

Por ejemplo, aquí está el ejemplo trabajado para usted:

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"
vy32
fuente
44
Produce un archivo vacío para mí
caspii
La primera ejecución está vacía y tampoco puede eliminarla, porque luego se abre en python. Segunda ejecución (o más preciso: out = csv.writer(open("myfile.csv","w"), delimiter=',',quoting=csv.QUOTE_ALL))llena los datos, sin importar si coloca open("myfile.csv","w")o un nuevo archivo open("myfile2.csv","w"). Parece que el objeto de salida no puede tratar con el objeto de archivo construido en la ejecución, pero almacena el proceso de salida como un todo. En otras palabras: ¡el objeto de salida almacena el objeto de archivo en la primera ejecución pero solo escribe cuando el objeto de archivo ya existe! Vea la solución correcta a continuación @Saurabh Adhikary
Lorenz
7

Podría usar el método string.join en este caso.

Divida en algunas líneas para mayor claridad: aquí hay una sesión interactiva

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

O como una sola línea

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

Sin embargo, puede tener un problema si sus cadenas tienen comillas incrustadas. Si este es el caso, deberá decidir cómo escapar de ellos.

El módulo CSV puede encargarse de todo esto por usted, permitiéndole elegir entre varias opciones de cotización (todos los campos, solo campos con comillas y separadores, solo campos no numéricos, etc.) y cómo eliminar los caracteres de control (comillas dobles, o cuerdas escapadas). Si sus valores son simples, string.join probablemente estará bien, pero si tiene que administrar muchos casos extremos, use el módulo disponible.

Robert Christie
fuente
3

Esta solución suena loca, pero funciona sin problemas como la miel

import csv

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

El archivo está siendo escrito por csvwriter, por lo tanto, las propiedades de csv se mantienen, es decir, separadas por comas. El delimitador ayuda en la parte principal al mover elementos de la lista a la siguiente línea, cada vez.

Saurabh Adhikary
fuente
1
Tan pequeño y tan rápido
Ian Samz
1
funciona, y si tiene una lista anidada, expandiendo el ejemplo de @ vy32, tiene: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
¿realmente suena loco? Creo que suena perfectamente bien
Stephanie Owen
3

Para crear y escribir en un archivo csv

El siguiente ejemplo muestra cómo crear y escribir un archivo csv. para crear un escritor de archivos dinámico, necesitamos importar un paquete de importación CSV , luego debemos crear una instancia del archivo con la referencia del archivo Ej: - con open ("D: \ sample.csv", "w", newline = "" ) como file_writer

aquí si el archivo no existe con el directorio de archivos mencionado, entonces python creará un mismo archivo en el directorio especificado, y "w" representa escritura, si desea leer un archivo, reemplace "w" con "r" o para agregar al archivo existente y luego "a". newline = "" especifica que elimina una fila vacía adicional por cada vez que crea una fila, por lo que para eliminar la fila vacía usamos newline = "", creamos algunos nombres de campo (nombres de columna) usando list like fields = ["Names", "Age "," Class "] , luego se aplica a la instancia de escritor como writer = csv.DictWriter (file_writer, fieldnames = fields) aquí usando Dictionary writer y asignando nombres de columna, para escribir nombres de columna en csv usamos escritor. , mientras que la escritura de valores de archivo debe pasarse utilizando el método de diccionario, aquí la clave es el nombre de la columna y el valor es su valor clave respectivo

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
fuente
2

Cuaderno Jupyter

Digamos que tu lista es A

Luego puede codificar el siguiente anuncio, lo tendrá como un archivo csv (¡solo columnas!)

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

seguramente debe usar el módulo CSV, pero lo más probable es que necesite escribir unicode. Para aquellos que necesitan escribir Unicode, esta es la clase de la página de ejemplo, que puede usar como módulo 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
fuente
1

Aquí hay otra solución que no requiere el csvmódulo.

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

Ejemplo:

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

Sin embargo, si la lista inicial contiene algunos ", no se escaparán. Si es necesario, es posible llamar a una función para escapar así:

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