Crie um arquivo .csv com valores de uma lista Python

181

Estou tentando criar um arquivo .csv com os valores de uma lista Python. Quando imprimo os valores na lista, eles são todos unicode (?), Ou seja, se parecem com isso

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

Se eu percorrer os valores da lista, ou seja, for v in mylist: print veles parecem ser texto sem formatação.

E eu posso colocar um ,entre cada um comprint ','.join(mylist)

E eu posso imprimir em um arquivo, ou seja

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

Mas eu quero enviar para um CSV e ter delimitadores em torno dos valores na lista, por exemplo

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

Não consigo encontrar uma maneira fácil de incluir os delimitadores na formatação, por exemplo, tentei a joindeclaração. Como posso fazer isso?

Fortilan
fonte
Obrigado a todos, eu combinei as idéias de algumas respostas para resolver minha pergunta :) Agora, uso o módulo csv para gravar os [...] dados diretamente em um arquivo import csv data = [...] myfile = open ( ..., 'wb') out = csv.writer (open ("myfile.csv", "w"), delimitador = ',', citando = csv.QUOTE_ALL) out.writerow (data) funciona bem, eu construo meus dados [] por pegar alguns dados a uma planilha usando xlrd eo módulo csv escreve-lo para um arquivo com os delimitadores direitos todas boas :) ty tudo de novo
Fortilan
Uma abordagem mais recente poderia ser a utilização de pandas
Richard
Usuários do Python 3.4, isso funcionou melhor para mim: stackoverflow.com/questions/25022677/…
Leigh
1
Consulte também: Como leio e escrevo arquivos CSV com Python?
Martin Thoma 03/02

Respostas:

252
import csv

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

Edit: isso só funciona com python 2.x.

Para fazê-lo funcionar com o python 3.x, substitua wbpor w( consulte esta resposta do SO )

with open(..., 'w', newline='') as myfile:
     wr = csv.writer(myfile, quoting=csv.QUOTE_ALL)
     wr.writerow(mylist)
Alex Martelli
fonte
11
Observe que o csvmódulo no 2.x não lida corretamente com unicodes; consulte a documentação do módulo para obter exemplos de como lidar com isso. docs.python.org/library/csv.html
Ignacio Vazquez-Abrams
14
você também pode usar wr.writerows (list)
tovmeod
4
O Writerows parece dividir cada elemento da lista em colunas se cada elemento também for uma lista. Isso é bastante útil para gerar tabelas.
Whatnick
6
Isso não funciona com o python 3.4. Eu estou recebendo TypeError: 'str' does not support the buffer interface.
Botchniaque 15/09/2015
1
Para Python 2, use 'w'como aqui: stackoverflow.com/questions/34283178/…
banan3'14
105

Aqui está uma versão segura do de Alex Martelli:

import csv

with open('filename', 'wb') as myfile:
    wr = csv.writer(myfile, quoting=csv.QUOTE_ALL)
    wr.writerow(mylist)
Cristian Garcia
fonte
3
mais 1 para usar with, certificando-se o arquivo é fechado quando feito
BoltzmannBrain
Se eu estiver usando isso dentro de um loop for, o bloco with inteiro deve ser aninhado no loop for? Ou seria mais eficiente ter apenas wr.writerow(my_list)dentro do loop?
Crypdick 7/06
1
@ Crypdick você definitivamente não deve colocar todo o bloco no loop. Abra o arquivo e, em seguida, escreva cada linha em um loop. Não é necessário abrir o arquivo n vezes para gravar n linhas.
perfil completo de Greg Kaleka
Se você estiver escrevendo objetos string em um arquivo, sugira usar 'wt' ao abrir o arquivo para evitar TypeError: é necessário um objeto semelhante a bytes, não 'str'.
don_Gunner94 4/03
41

Para outra abordagem, você pode usar o DataFrame nos pandas : e pode facilmente despejar os dados no CSV, como no código abaixo:

import pandas
df = pandas.DataFrame(data={"col1": list_1, "col2": list_2})
df.to_csv("./file.csv", sep=',',index=False)
Qy Zuo
fonte
1
Obrigado por este trecho de código, que pode fornecer ajuda imediata. Uma explicação adequada melhoraria bastante seu valor educacional, mostrando por que essa é uma boa solução para o problema e a tornaria mais útil para futuros leitores com perguntas semelhantes, mas não idênticas. Por favor edite sua resposta para adicionar explicação, e dar uma indicação do que limitações e premissas se aplicam.
precisa
5
Também para este trabalho as listas precisam ter o mesmo comprimento, caso contrário, você vai ter um ValueError (pandas v 0.22.0)
cheevahagadog
32

A melhor opção que encontrei foi usar o savetxtdo numpymódulo :

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

Caso você tenha várias listas que precisam ser empilhadas

np.savetxt("file_name.csv", np.column_stack((data1, data2)), delimiter=",", fmt='%s', header=header)
tokenizer_fsj
fonte
8
Isso é bom para o trabalho numérico, mas não funciona ao apresentar seqüências de caracteres na lista.
Ricardo Cruz
12

Use o csvmódulo python para ler e escrever arquivos delimitados por vírgula ou tabulação. O módulo csv é preferido, pois oferece um bom controle sobre a citação.

Por exemplo, aqui está o exemplo trabalhado para você:

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)

Produz:

"value 1","value 2","value 3"
vy32
fonte
4
Produz um arquivo vazio para mim
caspii
A primeira execução está vazia e você também não pode excluí-la, porque é aberta em python. Segunda execução (ou mais precisa: out = csv.writer(open("myfile.csv","w"), delimiter=',',quoting=csv.QUOTE_ALL))preenche os dados, independentemente de você colocar open("myfile.csv","w")um novo arquivo open("myfile2.csv","w"). Parece que o objeto out não pode lidar com o objeto de arquivo criado na execução, mas armazena o processo de saída como um todo. o objeto out armazena o objeto file na primeira execução, mas só está gravando quando o objeto file já existe! Veja a solução correta abaixo @Saurabh Adhikary
Lorenz
7

Você pode usar o método string.join nesse caso.

Divida algumas linhas para maior clareza - aqui está uma sessão interativa

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

Ou como uma única linha

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

No entanto, você pode ter um problema, pois suas strings possuem aspas incorporadas. Se for esse o caso, você precisará decidir como escapar deles.

O módulo CSV pode cuidar de tudo isso para você, permitindo escolher entre várias opções de cotação (todos os campos, apenas campos com aspas e separadores, apenas campos não numéricos, etc.) e como esacpe controlar caracteres (aspas duplas ou cordas escapadas). Se seus valores forem simples, string.join provavelmente estará OK, mas se você precisar gerenciar muitos casos extremos, use o módulo disponível.

Robert Christie
fonte
3

Esta solução parece loucura, mas funciona suave como mel

import csv

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

O arquivo está sendo gravado pelo csvwriter, portanto, as propriedades do csv são mantidas, isto é, separadas por vírgula. O delimitador ajuda na parte principal, movendo os itens da lista para a próxima linha, a cada vez.

Saurabh Adhikary
fonte
1
Tão pequeno e tão rápido
Ian Samz 16/01
1
funciona e, se você tiver uma lista aninhada, expandindo o exemplo do @ vy32, terá: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
soa realmente louco? Eu acho que soa perfeitamente bem
Stephanie Owen
3

Para criar e gravar em um arquivo csv

O exemplo abaixo demonstra a criação e gravação de um arquivo csv. para criar um gravador de arquivo dinâmico, precisamos importar um pacote import csv e , em seguida, criar uma instância do arquivo com a referência de arquivo Ex: - com open ("D: \ sample.csv", "w", newline = "" ) como file_writer

aqui, se o arquivo não existir com o diretório de arquivos mencionado, o python criará o mesmo arquivo no diretório especificado e "w" representa gravação, se você quiser ler um arquivo, substitua "w" por "r" ou anexe para o arquivo existente então "a". newline = "" especifica que ele remove uma linha vazia extra a cada vez que você cria uma linha. Para eliminar a linha vazia, usamos newline = "", crie alguns nomes de campos (nomes de colunas) usando uma lista como fields = ["Names", "Age "," Class "] e , em seguida, aplique à instância do writer como writer = csv.DictWriter (file_writer, fieldnames = fields) aqui usando o Dictionary writer e atribuindo nomes de colunas, para escrever nomes de colunas no csv, usamos writer. , enquanto a escrita dos valores do arquivo deve ser transmitida usando o método do dicionário, aqui a chave é o nome da coluna e o valor é o respectivo valor da chave

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

Caderno Jupyter

Digamos que sua lista seja A

Em seguida, você pode codificar o seguinte anúncio, que o terá como um arquivo csv (apenas colunas!)

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

você deve usar o módulo CSV com certeza, mas as chances são de que você precisa escrever unicode. Para aqueles que precisam escrever unicode, esta é a classe da página de exemplo, que você pode usar como um módulo utilitário:

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
fonte
1

Aqui está outra solução que não requer o csvmódulo.

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

Exemplo:

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

No entanto, se a lista inicial contiver alguns ", eles não serão escapados. Se for necessário, é possível chamar uma função para escapar dessa maneira:

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