質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

3回答

1373閲覧

Python リスト型のCSV出力の事例をネット記事からコピペするも、期待したとおり収まっていない!

saya24

総合スコア247

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2020/05/19 07:40

本件はこちらの案件に続く内容です。

リスト型のデータをCSV出力する機能を、ネットの記事から複写し、ご支援を頂きなんとかファイル出力まで至ったのですが
実際仕上がったファイルを開けてみると、期待する結果ではありませんでした。

・データ行が 文字単位に列へ格納されてしまっている
・1行のレコードを期待していたが、無駄に空白行が入っている
・1行のレコードを期待していたが、列展開ではなく、行展開されている
という点を解決したいです。

現況のコードは以下のとおりです。

Python

1import csv 2 3output_data = ["書き込む", "データ", "だよ"] 4 5with open("file.csv", "w") as f: 6 writer = csv.writer(f) 7 8 # csv用のヘッダーがデータにない場合は先に書いておく 9 writer.writerow(["header", "data", "だよ"]) 10 11 for data_row in output_data: 12 writer.writerow(data_row)

このコードから生成されたCSVファイルはこちらです。
あれれ

参考にした記事が良くないのでしょうか?(元の記事

【質問】
ヘッダを除くと 3列1レコードのCSVファイルを出力するには どういった変更を 当該コードに加えればよろしいのでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ヘッダー出力同様に下記で良いのではないでしょうか?

Python

1writer.writerow(output_data)

投稿2020/05/19 08:23

meg_

総合スコア10760

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

saya24

2020/05/20 00:20

meg_さん ご見解ありがとうございます、試させて頂きました。 For文の代替えで ご提示のようにしましたら、目的のレコードが列展開されました。 ただ、ヘッダ行と実際今回無事に出力されたレコードの間に 空白があらわれておりました。 引き続き、他の方のご見解を試してまいりますね。貴重なお時間を頂きありがとうございました。
guest

0

python

1 for data_row in output_data: 2 writer.writerow(data_row)

の部分で、output_dataを分解して1行ずつ書き込んでますよね?このままでは文字毎に分解されてしまいますので、複数行を想定するなら、

python

1output_data = [["書き込む", "データ", "だよ"]]

と定義するべきでしょう。
また、空白行が入るのはWindows環境だからです。openするときに、

python

1with open("file.csv", "w", newline='') as f:

としてみてください。

投稿2020/05/19 07:57

x98000

総合スコア1096

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

saya24

2020/05/20 00:28

x98000さん ありがとうございます、無事に期待の結果を得られました。 For文をちゃんと理解すれば文字単位にでることは当然の結果でしたね、ご説明頂きありがとうございました。Windowsの場合は、ファイルオープン時に改行のオプションを指定する必要があったのですね。 非常に丁寧な説明で助かりました。
guest

0

ベストアンサー

CSV は、N行M列の表データを表す形式なので、output_data は1次元配列ではなく、2次元配列となっているべきではないでしょうか。

python

1import csv 2 3output_data = [ 4 # 1列目 2列目 3列目 5 ["AAA", "BBB", "CCC"], # 1行目 6 ["AAA", "BBB", "CCC"], # 2行目 7 ["AAA", "BBB", "CCC"], # 3行目 8 ["AAA", "BBB", "CCC"], # 4行目 9] 10 11with open("file.csv", "w") as f: 12 writer = csv.writer(f) 13 14 # csv用のヘッダーがデータにない場合は先に書いておく 15 writer.writerow(["header", "data", "だよ"]) 16 17 for data_row in output_data: 18 writer.writerow(data_row)

参考にした記事が良くないのでしょうか?

おかしいので別のサイトを参考にしたほうがいいと思います。

追記

コメントのような辞書のリストになっているのであれば、csv.DictWriter を使えば、変換なしにそのまま書き込めます。

python

1import csv 2 3output_data = [ 4 {"Name": "Alice", "Age": 40, "Point": 80}, 5 {"Name": "Bob", "Age": 20, "Point": 60}, 6 {"Name": "Charlie", "Age": 30, "Point": 70}, 7] 8 9header = list(output_data[0].keys()) # 列の順番を規定 10print(header) # ['Name', 'Age', 'Point'] 11 12with open("output.csv", "w", newline="") as f: 13 writer = csv.DictWriter(f, fieldnames=header) 14 writer.writeheader() # ヘッダーを書き込む 15 writer.writerows(output_data) # データを書き込む

出力結果

csv

1Name,Age,Point 2Alice,40,80 3Bob,20,60 4Charlie,30,70

投稿2020/05/19 07:56

編集2020/05/20 03:30
tiitoi

総合スコア21956

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

saya24

2020/05/20 01:10

titoiさん、ありがとうございます。ご丁寧に複数レコードがあった場合の事例を示して頂き、よくイメージを捉えることができました。 レコード間に空白レコードが挿入される問題が発生しましたので、ご提示のコードにx98000さんのご見解を織り交ぜ、ファイルオープン部分にnewline=''の追加指定をすることで 期待の行列展開を無事達成することができました。 CSVデータの作成においては 予めこの形式に整えた上で投入手続きに入ることを自分のスタンダードにしたいと思います。 というのは...現在取り組んでいるプログラムが データベースからのデータを l = [{'Name': 'Alice', 'Age': 40, 'Point': 80}, {'Name': 'Bob', 'Age': 20, 'Point': 60}, {'Name': 'Charlie', 'Age': 30, 'Point': 70}] という辞書形式で捉えているんです。 ご提示のList型の形式に一度変換する手立てを挟むことは 妙ではないですよね?? 別スレッドで確認したほうがよろしいですかねぇ?? 他人様が自分のコード(当方が提示した形式をリスト型に変換した上でCSV出力している手順)をご覧になられた際に、非常識なことをしている と思われたはくなく
saya24

2020/05/20 02:20

一応、仕掛中のプログラムが捉えているデータ集団の形式を(辞書型配列)をレコード単位のリスト型を形成しながら CSV出力する手続きを作ってみました。できた、といえばできたので良いのですが 非常識なことはやっていませんかね... import csv output_data = [{'Name': 'Alice', 'Age': 40, 'Point': 80}, {'Name': 'Bob', 'Age': 20, 'Point': 60}, {'Name': 'Charlie', 'Age': 30, 'Point': 70}] with open("file.csv", "w", newline="") as f: writer = csv.writer(f) # ヘッダー dict_header = output_data[0] header = list(dict_header.keys()) writer.writerow(header) for data_row in output_data: writer.writerow(list(data_row.values()))
saya24

2020/05/20 02:28

インデントが崩れて見えるのは ご容赦ください。
tiitoi

2020/05/20 03:29

追記しました。このような意図であっていますか。
saya24

2020/05/20 03:52

ありがとうございます、合っています。そして試してみて、期待の結果を得られることを確認しました。 やはり聞いてよかったです。 世間一般的でない解決策だと、あとから自分のコードを覗いた方に対し 恥ずかしいので。 本件クローズします、至れり尽くせりの対応感謝を申し上げます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問