#小川先生のサンプルを参考に作成
import csv
from pathlib import Path
import pprint
base_path = Path(__file__).parent
#読み取りCSV
csv_file_path = base_path / 'screening' / 'screening_20221005132428.csv'
#書き出しCSV
by_write_path = base_path / 'screening' / 'csv_cashflow_new.csv'
with csv_file_path.open(mode='r', encoding='shift_jis') as file:
reader = csv.DictReader(file)
for row in reader:
print(row)
#for k, v in row.items():
#カンマがあると文字列を数値化が出来ないようなのでカンマを空白に置き換え
cf = row['営業CF'].replace(",", "")
eq = row['発行済株式総数'].replace(",", "")
#配当総支払額(配当*発行済み株数が営業CFの40%を超える場合削除する
cf_haitou_hiritsu = float(eq) * float(row['配当金(前期)']) / int(cf) / 1000000
if cf_haitou_hiritsu > 0.4:
row.clear()
#readerの中身を確認
#pprint.pprint(reader)
with by_write_path.open(mode='w', encoding='utf-8', newline='') as f:
fieldnames = ['銘柄コード', '会社名', '決算月', '配当金(前期)', '配当金(会予)', '発行済株式総数']
writer = csv.DictWriter(f, fieldnames=fieldnames, extrasaction='ignore')
writer.writeheader()
writer.writerow(reader)
【エラ-文】
C:\mypython\Eq_sclayPing\venv\Scripts\python.exe C:/mypython/Eq_sclayPing/Reas_Csv_Screening.py
Traceback (most recent call last):
File "C:\mypython\Eq_sclayPing\Reas_Csv_Screening.py", line 35, in <module>
writer.writerow(reader)
File "C:\Users\hutsu\AppData\Local\Programs\Python\Python310\lib\csv.py", line 154, in writerow
return self.writer.writerow(self._dict_to_list(rowdict))
File "C:\Users\hutsu\AppData\Local\Programs\Python\Python310\lib\csv.py", line 151, in <genexpr>
return (rowdict.get(key, self.restval) for key in self.fieldnames)
AttributeError: 'DictReader' object has no attribute 'get'
2022/10/06 06:34
小川 慶一さんのコメント
(コメントID: 7896)
おー、興味深い失敗例ですね v(^^*
まず、前提知識を整理しておきます。 with ... で開いたファイルは、with ブロックが終わったタイミングで自動的に閉じられます。
つまり、以下の[a], [b] は同じ処理です。
import csv
from pathlib import Path
base_path = Path(__file__).parent
csv_file_path = base_path / 'screening' / 'screening_20221005132428.csv'
# [a] with を使わない書き方
file = csv_file_path.open(mode='r', encoding='shift_jis')
reader = csv.DictReader(file)
for row in reader:
print(row)
file.close()
# [b] with を使った書き方
with csv_file_path.open(mode='r', encoding='shift_jis') as file:
reader = csv.DictReader(file)
for row in reader:
print(row)
靭 宏明さんの投稿
(投稿ID: 5402) 添付ファイルのダウンロード権限がありません
靭です。CSVの辞書での読み取りと書き出しで嵌まってしまいました。
やりたいことはCSVを読み込んだ後、IF文で該当しないデ-タを除いて別名ファイルを一部項目だけを対象に
作ることですが、下記メッセージが出てCSVが作成出来ません。
記載コ-ドは下記で、実際に使用したCSVは添付ですがどこに問題があるかご指導いただけないでしょうか
【エラ-文】
小川 慶一さんのコメント
(コメントID: 7896)
まず、前提知識を整理しておきます。
with ... で開いたファイルは、with ブロックが終わったタイミングで自動的に閉じられます。
つまり、以下の[a], [b] は同じ処理です。
そして、closeされたあとにファイルにアクセスしようとするとエラーになります。
csvDictReaderはあくまで「読み込み装置」です。
以下であれば、[1] の段階では、まだ「読み込み準備が整っただけ」で、「読み込み完了状態」ではありません。
実際に読み込みを行うのは、[2]のタイミングです。
ということで、以下のNGとされているコードはエラーになります。
reader が読み込もうとしたファイルはすでに close されているからです。
ということで、ではどのように問題を回避するかというと、以下のどちらかということになるかと思います。
1. with を入れ子にして、読み込んだファイルが自動的に close() される前に書き込みもしてしまう。
2. 読み込んだファイルから得た情報をリストに入れておき、書き込み時は、そのリストから値を読み込む。
1. with を入れ子にして、読み込んだファイルが自動的に close() される前に書き込みもしてしまう。
読み込み用のファイルを close する前に csv.DictReader(file) でひと仕事終えてしまおうということです。
2. 読み込んだファイルから得た情報をリストに入れておき、書き込み時は、そのリストから値を読み込む。
これだと、以下の方針になります。
2-1. csv.DictReader(file) で得られた情報はいったんリストにいておく。
2-2. 読み込み用のファイルは閉じる。
2-3. 書き込み用のファイルを開く。
2-4. 2-1で作ったリストを使って書き込みを行う。
靭 宏明さんのコメント
(コメントID: 7899)
小川 慶一さんのコメント
(コメントID: 7903)
> LISTで書き込む時、この場合はfor 文で書き込む必要があったのですね。
いえ、その理解は適切ではありません。
前の投稿にも書いたとおり、closeされたあとにファイルにアクセスしようとことが問題です。
書き込みの部分は、上記の問題をクリアしていれば、writerowsにリストを渡しても問題なく動きます。
以下のとおりです。
靭 宏明さんのコメント
(コメントID: 7905)