csvファイルの読み書き

# はじめに
 [CS50P]( https://cs50.harvard.edu/python/2022/ )の課題で必要になった知識を自分の理解を深めるために記述していきます。

## csv.reader と csv.writer
csvファイルをの読み込みと書き込みをしたいと思います。
[Pythonの公式ドキュメント](https://docs.python.org/3/library/csv.html)を参考にしていきます。

### リスト型csvファイルの読み込み
下記のような記述でcsvファイルを読み込むことができます。

```Python:csv読み込み
import csv
with open('eggs.csv', newline='') as csvfile:
    spamreader = csv.reader(csvfile, delimiter=' ', quotechar='|')
    for row in spamreader:
        print(', '.join(row))
#Spam, Spam, Spam, Spam, Spam, Baked Beans
#Spam, Lovely Spam, Wonderful Spam
```
上記の構造は...
- __import csv__ :  'csv'というcsvファイルを扱うモジュールを読み込んでいます。
- __with open(‘eggs.csv’, newline=‘’) as csvfile__ : ": eggs.csvというファイルを開いています。newline=’'というオプションは、改行文字(\n)を削除するためのオプションです。as csvfileという部分は、開いたファイルをcsvfileという変数に代入するための部分です。
- __spamreader = csv.reader(csvfile, delimiter=’ ‘, quotechar=’|‘)__ : csv.readerという関数は、csvモジュールに定義されている関数。csvfileという引数は、読み込むファイルのオブジェクト。delimiter=’ ‘というオプションは、区切り文字をスペースにするためのオプション。quotechar=’|'というオプションは、引用符("Shinjuku, Tokyo"における"")を|にするためのオプション。作ったオブジェクトをspamreaderという変数に代入しています。
- __for row in spamreader:__ : spamreaderから一行ずつデータを取り出して繰り返し処理するための文。forというキーワードは、反復処理を行うための構文。rowという変数は、(一行ずつ）取り出したデータを格納するための変数。in spamreaderという部分は、取り出すデータの元になるオブジェクトを指定するための部分です。
- __print(', ‘.join(row))__ : 取り出したデータをカンマで連結して表示するための文。printという関数は、引数を画面に表示するための関数です。’, ‘.join(row)という部分は、rowというリストの要素を’, 'という文字列で連結するための式です。

以上により下記の結果が出力されます
```
Spam, Spam, Spam, Spam, Spam, Baked Beans
Spam, Lovely Spam, Wonderful Spam
```

### リスト型csvファイルの書き込み
同様にしてcsvの書き込みを見て行きます。
```python:csv書き込み
import csv
with open('eggs.csv', 'w', newline='') as csvfile:
    spamwriter = csv.writer(csvfile, delimiter=' ',
                            quotechar='|', quoting=csv.QUOTE_MINIMAL)
    spamwriter.writerow(['Spam'] * 5 + ['Baked Beans'])
    spamwriter.writerow(['Spam', 'Lovely Spam', 'Wonderful Spam'])
```

構造を見ていきます。（読み込みと被る内容は割愛します。）
- __with open(‘eggs.csv’, ‘w’, newline=‘’) as csvfile:__ : eggs.csvというファイル用を書き込み用に開いている。‘w’というオプションは、書き込み用に開くためのオプション。
- __spamwriter = csv.writer(csvfile, delimiter=’ ‘, quotechar=’|‘, quoting=csv.QUOTE_MINIMAL)__ : csv.writerという関数を呼び出して、csvfileにデータを書き込むオブジェクトを作っている。csvfileという引数は、書き込むファイルのオブジェクト。quoting=csv.QUOTE_MINIMALというオプションは、データに応じて引用符を使うかどうかを決めるためのオプション。
- __spamwriter.writerow([‘Spam’] * 5 + [‘Baked Beans’])__ : spamwriterのwriterowというメソッドを呼び出し、[‘Spam’, ‘Spam’, ‘Spam’, ‘Spam’, ‘Spam’, ‘Baked Beans’]というリストを一行目に書き込んでいる。このリストの要素は、スペースで区切られてCSVファイルに書き込まれる。つまり、一行目はSpam Spam Spam Spam Spam Baked Beansとなる。
- __spamwriter.writerow([‘Spam’, ‘Lovely Spam’, ‘Wonderful Spam’])__ : spamwriterのwriterowというメソッドを呼び出し、[‘Spam’, ‘Lovely Spam’, ‘Wonderful Spam’]というリストを二行目に書き込んでいる。このリストの要素も同様にスペースで区切られてCSVファイルに書き込まれる。ただし、Lovely SpamやWonderful Spamなどのスペースが含まれる要素は|で囲まれて引用符が付けられる。つまり、二行目はSpam |Lovely Spam| |Wonderful Spam|となる。

## csv.Dicreader と csv.Dicwriter
前述の読み込み・書き込みはリスト型でしたが次は辞書型を扱っていきます。

### 辞書型csvファイルの読み込み
まずは読み込みを見て行きます。(既に記述した要素は説明を省きます。）
```python:辞書化型csvの読み込み
import csv
with open('names.csv', newline='') as csvfile:
    reader = csv.DictReader(csvfile)
    for row in reader:
        print(row['first_name'], row['last_name'])
# Eric Idle
# John Cleese

print(row)
# {'first_name': 'John', 'last_name': 'Cleese'}
```
上記の構造は
- __reader = csv.DictReader(csvfile)__ : csv.DictReaderというクラスを呼び出して、辞書型のcsvfileからデータを読み込むオブジェクトを作成。
- __print(row[‘first_name’], row[‘last_name’])__ : 取り出したデータを表示。row[‘first_name’]やrow[‘last_name’]という部分は、rowという辞書型（キーと値のペアの集まり）のデータから特定のキーに対応する値を取り出すための式。


### 辞書型csvファイルの書き込み
続いて辞書型データの書き込みについて
```python:辞書化型csvの書き込み
import csv

with open('names.csv', 'w', newline='') as csvfile:
    fieldnames = ['first_name', 'last_name']
    writer = csv.DictWriter(csvfile, fieldnames=fieldnames)

    writer.writeheader()
    writer.writerow({'first_name': 'Baked', 'last_name': 'Beans'})
    writer.writerow({'first_name': 'Lovely', 'last_name': 'Spam'})
    writer.writerow({'first_name': 'Wonderful', 'last_name': 'Spam'})
```

上記の構造は
- __fieldnames = ['first_name', 'last_name']__ : CSVファイルのヘッダー行（カラムのタイトル）で使用する列の名前を指定。この場合、'first_name'と'last_name'の2つの列。
- __writer = csv.DictWriter(csvfile, fieldnames=fieldnames)__ : csv.DictWriterオブジェクトを作成。fieldnamesはヘッダー行の列名を指定(右側が1つ前の行で指定されたオブジェクト）。
- __writer.writeheader():__ : CSVファイルのヘッダー行を書き込み。この行には列名が含まれ、この場合、'first_name'と'last_name'がヘッダー行に書き込まれる。
- __writer.writerow({'first_name': 'Baked', 'last_name': 'Beans'})__ : 辞書型データを使用して、CSVファイルに1行のデータを書き込む。この行では、'first_name'列に'Baked'、'last_name'列に'Beans'という値が書き込まれる。

以上の結果出力されるファイルは下記のようになる。
```
first_name,last_name
Baked,Beans
Lovely,Spam
Wonderful,Spam
```

以上、簡単な部分ですがまとめてみました！