(ファイルではなく)文字列としてCSV形式でデータを書き込むにはどうすればよいですか?


119

データ[1,2,'a','He said "what do you mean?"']をCSV形式の文字列にキャストしたい。

csv.writer()クレイジーエッジケース(カンマエスケープ、引用符エスケープ、CSV方言など)をすべて処理するため、通常はこれを使用します。キャッチはcsv.writer()、文字列ではなくファイルオブジェクトに出力することを想定しています。

私の現在の解決策は、このややハックな機能です:

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

誰もがまだエッジケースをうまく処理するよりエレガントなソリューションを与えることができますか?

編集:これが私がそれをやった方法です:

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

2
Python 3ではStringIO()ioライブラリにあります。
アリスティド

回答:


66

あなたStringIO自身の代わりに使用することができますDummy_Writer

このモジュールStringIOは、文字列バッファ(メモリファイルとも呼ばれます)を読み書きするファイルのようなクラスを実装します。

クラスのcStringIOより高速なバージョンであるもありStringIOます。


164

Python 3の場合:

>>> 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では、いくつかの詳細を少し変更する必要があります。

>>> 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'

良い例え。:)補足として、CSVファイル内で改行が発生した場合の通常の動作は何ですか?ある\nデータの真ん中に持って[OK]を、しかし\r\n、それが表示されていない問題は、レコードの末尾を示しますか?(\r\nラインターミネーターとして使用するプラットフォームを使用していると仮定します。)
Li-aung Yip

2
である必要がoutput = StringIO.StringIO()ありio.StringIO()ます。TypeErrorが発生します:文字列引数が必要ですが、'str'を取得しました。
Marboni

2
@Marboni:StringIOはPython 3(私のソリューションが記述されているもの)でなくなっており、Python 2.7.3ではそのエラーを再現できません- writer.writerow(...)行(unicode argument expected, got 'str')でTypeErrorが発生しますが。これを調べます。
Tim Pietzcker、2012年

1
@Marboni:ヘッドアップをありがとう:StackOverflowの助けを借りて問題見つけました。Python 2では、のio.BytesIO()代わりにが必要ですio.StringIO()
Tim Pietzcker、2012年

1
@Marboni:Python 2.7.9では、StringIO.StringIO()またはio.BytesIO()で動作します。
2015年

6

答えは、全体として少しわかりにくいものでした。Python 2の場合、この使用法は私にとってうまくいきました:

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

csvデータとして次のPython 3のスニペットを記述したので、これを使用して、サニックからユーザーに非同期で結果を非同期でストリーミングします。

スニペットを使用すると、同じStringIoバッファを何度も再利用できます。


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"

例:

csv_formatter = ArgsToCsv()

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

github gist:sourceと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
コードのみの回答はお勧めできません。回答に説明を追加してください
Raniz

-1

これがutf-8で動作するバージョンです。1行のみのcsvline2string、最後に改行なし、csv2stringは多くの行、改行あり:

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()
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.