関数化してみた
先日から作成しているcsvをjsonに変換するプログラムですが、これまでjson出力部分のみ関数で他はベタ書きだったのを機能ごとに関数に分割してみました。
# coding: shift_jis #CSVを読み込んでJSON化する import sys import codecs from collections import OrderedDict def csvreader(tFileName, delimiter=","): """read csv file, convert to list of dict, and return it""" #読み出しで開く tFile = open(tFileName, 'r') #行のリストを作成 eachLine = [] for line in tFile: eachLine.append(line.replace("\n", "") .replace('\"', '') .replace("\'", "")) tFile.close() eachPart = [""] * len(eachLine) #各行をカンマで分割 for i, v in enumerate(eachLine): eachPart[i] = v.split(delimiter) #キーのリスト keyList = eachPart.pop(0) #dictのリストを作る eachDict = [""] * len(eachPart) for i, v in enumerate(eachPart): eachDict[i] = OrderedDict() if len(keyList) != len(eachPart[i]): print "Item #" + str(i) + " length adjust" #キーの長さより要素数が少ない場合は""で埋める if len(keyList) > len(eachPart[i]): gap = len(keyList) - len(eachPart[i]) eachPart[i].extend(gap * [""]) for j, vj in enumerate(keyList): eachDict[i][vj] = unicode((eachPart[i][j]), "shift_jis") return eachDict def jsonwriter(tFileName, tDict): """write tDict to tFile as json""" tFile = codecs.open(tFileName, "w", "utf-8") tFile.write(u"[\n") #先頭の[ outerComFlg = u"" #2行目以降に改行とコンマを書き込むフラグ for line, dummy in enumerate(tDict): tFile.write(outerComFlg + u" {") outerComFlg = u",\n" comFlg = u"" #行内の2要素目以降の先頭にコンマを書き込むフラグ for i, v in tDict[line].iteritems(): tStr = comFlg + u'\"' + i + u'\":\"' + v + u'\"' tFile.write(tStr) comFlg = u"," tFile.write(u"}") tFile.write(u"\n]") tFile.close() def main(): if sys.argv[1].endswith(".csv"): csvFileName = sys.argv[1] else: csvFileName = sys.argv[1] + ".csv" tDict = csvreader(csvFileName) jsonFileName = csvFileName.replace(".csv", ".json") jsonwriter(jsonFileName, tDict) if __name__ == "__main__": main()
全体のコードが長くなってきたのでブログに載せる際にも不便だったのですが、今後は改造した関数単位で載せられるのでムダにスペース使わなくて済みます。分割と言ってもcsvを読む部分、jsonとして出力する部分、main()の3つですが。
これまで特に理由はなくカンマで区切られたcsvを前提としていましたが別に区切りはカンマじゃなくてもいいなと思い、区切り文字は引数で渡せるようにしてみました。