複数のCSVファイルを共通のキーで結合する (悪い例)
bonlifeです。「Pythonを使って、複数のCSVファイルを共通のキーを使って結合する」を見て、csvデータ扱うのなら、常識的に考えてcsvモジュールだろ!と思ってしまいましたよ。いうことで、無理してcsvモジュール使ったサンプルを書いたら結構ヒドイことになってしまった…orz 元のコードの方が256倍ぐらい読みやすい気がします。
こだわったポイントは、辞書のキーを変えたり、無理矢理リストにしたりしながら、最終的にcsv.DictWriterでドーンッ!て書き込めるようにしたところです。何だか色々と間違ってる気がしますよ、えぇ。(だって、DictWriterの説明、ほとんどないんだもの!!)
#! /usr/bin/env python # -*- coding: utf-8 -*- import os import csv def generate_each_dict(f): reader = csv.reader(open(f,"rb")) d = dict() for row in reader: d[row[0]] = row[1] return d def generate_all_dict(fl): d = dict() for i in fl: # dictionary's key is file name without extension d[os.path.splitext(i)[0]] = generate_each_dict(i) return d def generate_country_set(d): country_set = set() for i in d.values(): country_set.update(i.keys()) return country_set def change_key_of_dict(d,cs): # key change (file name to country code) changed_dict = dict() for c in cs: for i in d.iteritems(): if c in i[1].keys(): if c in changed_dict.keys(): changed_dict[c].update({i[0]:i[1][c]}) else: changed_dict.update({c:{i[0]:i[1][c]}}) return changed_dict def dict_to_list(d): result_list = list() for i in d.iteritems(): i[1]['country'] = i[0] result_list.append(i[1]) return result_list def merge_csv_to_csv(file_list,out_file_name): original_dict = generate_all_dict(file_list) header = original_dict.keys() changed_dict = change_key_of_dict(original_dict, generate_country_set(original_dict)) result_list = sorted(dict_to_list(changed_dict),key=lambda x: x.get('country')) header.sort() header.insert(0,'country') header_dict = dict() for i in header: header_dict[i] = i result_list.insert(0,header_dict) out = open(out_file_name,"wb") out.write(",".join(header)) writer = csv.DictWriter(open(out_file_name,"wb"),header) writer.writerows(result_list) if __name__ == "__main__": file_list = ["A.csv","B.csv"] # A.csv # JPN, 500 # USA,2000 # B.csv # USA,3000 # CHN, 100 merge_csv_to_csv(file_list,"out.csv") # out.csv # country, A, B # CHN, , 100 # JPN, 500, # USA,2000,3000