csvモジュールにはこのためのDictWriterクラスがあり、これは別のSO回答で非常にうまくカバーされています。重要な点は、DictWriterをインスタンス化するときに、すべての列見出しを知る必要があるということです。list_of_dictsからフィールド名のリストを作成できます。その場合、コードは次のようになります。
list_of_dicts = [{'hello': 'goodbye'}, {'yes': 'no'}]
out_path= "/docs/outfile.txt"
out_file = open(out_path, 'wb')
fieldnames = sorted(list(set(k for d in list_of_dicts for k in d)))
writer = csv.DictWriter(out_file, fieldnames=fieldnames, dialect='excel')
writer.writeheader() # Assumes Python >= 2.7
for row in list_of_dicts:
writer.writerow(row)
out_file.close()
フィールド名を作成した方法では全体がスキャンlist_of_dicts
されるため、サイズが大きくなると速度が低下します。代わりに、データのソースから直接構築する必要fieldnames
があります。たとえば、データのソースがcsvファイルでもある場合は、DictReaderを使用してを使用できますfieldnames = reader.fieldnames
。
for
ループを1回の呼び出しに置き換え、ブロックをwriter.writerows(list_of_dicts)
使用してwith
ファイルのクロージャーを処理することもできます。その場合、コードは次のようになります。
list_of_dicts = [{'hello': 'goodbye'}, {'yes': 'no'}]
out_path= "/docs/outfile.txt"
fieldnames = sorted(list(set(k for d in list_of_dicts for k in d)))
with open(out_path, 'wb') as out_file:
writer = csv.DictWriter(out_file, fieldnames=fieldnames, dialect='excel')
writer.writeheader()
writer.writerows(list_of_dicts)