Verileri CSV formatına dize (dosya değil) olarak nasıl yazabilirim?


119

Verileri [1,2,'a','He said "what do you mean?"']CSV biçimli bir dizeye benzer şekilde yayınlamak istiyorum .

Normalde bunun için kullanılır csv.writer(), çünkü tüm çılgın uç durumları ele alır (virgül kaçışı, tırnak işareti kaçışı, CSV lehçeleri, vb.) Yakalama, csv.writer()bir dizgeye değil, bir dosya nesnesine çıktı almayı beklemektir.

Şu anki çözümüm bu biraz hilekâr işlev:

def CSV_String_Writeline(data):
    class Dummy_Writer:
        def write(self,instring):
            self.outstring = instring.strip("\r\n")
    dw = Dummy_Writer()
    csv_w = csv.writer( dw )
    csv_w.writerow(data)
    return dw.outstring

Kimse, uç durumları iyi idare eden daha zarif bir çözüm verebilir mi?

Düzenleme: İşte bunu nasıl yaptım:

def csv2string(data):
    si = StringIO.StringIO()
    cw = csv.writer(si)
    cw.writerow(data)
    return si.getvalue().strip('\r\n')

2
Python 3, StringIO()olduğu iokütüphanede.
Aristide

Yanıtlar:


67

Kendiniz StringIOyerine kullanabilirsiniz Dummy_Writer:

Bu modül, StringIObir dizgi tamponu (bellek dosyaları olarak da bilinir) okuyan ve yazan dosya benzeri bir sınıf uygular .

Orada da cStringIOdaha hızlı bir versiyonu olan StringIOsınıfın.


165

Python 3'te:

>>> import io
>>> import csv
>>> output = io.StringIO()
>>> csvdata = [1,2,'a','He said "what do you mean?"',"Whoa!\nNewlines!"]
>>> writer = csv.writer(output, quoting=csv.QUOTE_NONNUMERIC)
>>> writer.writerow(csvdata)
59
>>> output.getvalue()
'1,2,"a","He said ""what do you mean?""","Whoa!\nNewlines!"\r\n'

Python 2 için bazı detayların biraz değiştirilmesi gerekiyor:

>>> output = io.BytesIO()
>>> writer = csv.writer(output)
>>> writer.writerow(csvdata)
57L
>>> output.getvalue()
'1,2,a,"He said ""what do you mean?""","Whoa!\nNewlines!"\r\n'

İyi örnek. :) Bir yan not olarak, bir CSV dosyasında yeni satırlarla karşılaşıldığında olağan davranış nedir? \nVerilerin ortasında olması uygun mudur , ancak \r\nnerede görünürse görünsün bir kaydın sonunu belirtir mi? ( \r\nHat sonlandırıcı olarak kullanan bir platformda olduğunuzu varsayarsak .)
Li-aung Yip

2
Olmalı output = StringIO.StringIO(), io.StringIO()TypeError'ı yükseltecek: string argümanı bekleniyor, 'str' var.
Marboni

2
@Marboni: StringIO Python 3'te gitti (çözümümün yazdığı şey bu) ve bu hatayı Python 2.7.3'te yeniden oluşturamıyorum - writer.writerow(...)( unicode argument expected, got 'str') satırında bir TypeError alsam da . Bunu araştıracak.
Tim Pietzcker

1
@Marboni: Uyarı için teşekkürler: Sorunu StackOverflow'un yardımıyla buldum . Python 2'de io.BytesIO()bunun yerine ihtiyacınız var io.StringIO().
Tim Pietzcker

1
@Marboni: Python 2.7.9'da StringIO.StringIO () veya io.BytesIO () ile çalışır.
srock

6

Sonuçta cevapları biraz kafa karıştırıcı buldum. Python 2 için bu kullanım benim için çalıştı:

import csv, io

def csv2string(data):
    si = io.BytesIO()
    cw = csv.writer(si)
    cw.writerow(data)
    return si.getvalue().strip('\r\n')

data=[1,2,'a','He said "what do you mean?"']
print csv2string(data)

2

Sanic'den kullanıcıya csv verisi olarak sonuçları eşzamansız olarak yayınlamak için bunu epeyce kullandığım için Python 3 için aşağıdaki parçacığı yazdım .

Parçacık, aynı StringIo arabelleğini tekrar tekrar kullanmanıza izin verir.


import csv
from io import StringIO


class ArgsToCsv:
    def __init__(self, seperator=","):
        self.seperator = seperator
        self.buffer = StringIO()
        self.writer = csv.writer(self.buffer)

    def stringify(self, *args):
        self.writer.writerow(args)
        value = self.buffer.getvalue().strip("\r\n")
        self.buffer.seek(0)
        self.buffer.truncate(0)
        return value + "\n"

misal:

csv_formatter = ArgsToCsv()

output += csv_formatter.stringify(
    10,
    """
    lol i have some pretty
    "freaky"
    strings right here \' yo!
    """,
    [10, 20, 30],
)

Github özetinde daha fazla kullanıma göz atın: kaynak ve test


0
import csv
from StringIO import StringIO
with open('file.csv') as file:
    file = file.read()

stream = StringIO(file)

csv_file = csv.DictReader(stream)

3
Yalnızca kod yanıtları tavsiye edilmez, yanıtınıza biraz açıklama eklemelisiniz
Raniz

-1

İşte utf-8 için çalışan sürüm. csvline2string tek bir satır için, sonunda satır sonu olmadan, birçok satır için csv2string, satır sonu ile:

import csv, io

def csvline2string(one_line_of_data):
    si = BytesIO.StringIO()
    cw = csv.writer(si)
    cw.writerow(one_line_of_data)
    return si.getvalue().strip('\r\n')

def csv2string(data):
    si = BytesIO.StringIO()
    cw = csv.writer(si)
    for one_line_of_data in data:
        cw.writerow(one_line_of_data)
    return si.getvalue()
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.