頭の体操
例えば、「メールアドレス,名前」が一行ずつ入ったファイルがあったとする。
[yasui@MacMini: ~/python/maptest][21:07] $ head random.cvs bsui9kbW@pdx.ne.jp,7lupVA5K5xdK OKQESJFx@docomo.ne.jp,CN2eBnufqLeC x748QoWF@ezweb.ne.jp,Bjc59Fc00xf4 nThpcgO4@yahoo.com,i8LUPvaMl7zL MPvkh1Qk@yahoo.com,3Leue9dNbYLU H76Mgo27@softbank.ne.jp,diveXAW71eDE w2O6vZ5Q@yahoo.co.jp,6V71YSZIHYIW ufvsHaA2@yahoo.com,R32ckgiPjA4j umN2jD1B@yahoo.co.jp,24SNduqD6Lmy vFR35ewI@yahoo.com,kDNvd5JuD9zA [yasui@MacMini: ~/python/maptest][21:07] $
これを、メールアドレスのみホスト順で並べて表示する。
特に何も考えずにサックリ書いたのがこんな感じ。
#!/usr/bin/env python # -*- coding: utf_8 -*- import sys import os def compare (x,y): xm = x[0] ym = y[0] xh = xm[xm.rindex('@')+1:].upper() yh = ym[ym.rindex('@')+1:].upper() # return cmp(xh, yh) if xh == yh: return 0 elif xh > yh: return 1 else: return -1 def srt (fn): return sorted(map(lambda f: (f[0:f.index(',')], f[f.index(',')+1:]), fn), cmp=compare) if __name__ == '__main__': if len(sys.argv) == 0: print "Cannot file name set." sys.exit(1) filename = os.path.abspath(sys.argv[1]) if os.path.exists(filename): for mail, name in srt(open(filename,'r')): print "%s" % ( mail) else: print "Not found file: %s" % (filename) sys.exit(1) sys.exit(0)
では、メールアドレスのリストを「random.cvs」に保存して、実行する。
[yasui@MacMini: ~/python/maptest][21:28] $ /usr/bin/time ./sort.py random.cvs (ry pKQdx0sy@yamoo.jp zxeS6PNO@yamoo.jp DrtdQ4AR@yamoo.jp n4I50Jcm@yamoo.jp KdFNqaQO@yamoo.jp eEcL7gsw@yamoo.jp 1.70 real 1.24 user 0.16 sys [yasui@MacMini: ~/python/maptest][21:29] $ wc -l random.cvs 61995 random.cvs [yasui@MacMini: ~/python/maptest][21:29] $
出力結果は途中割合。6万行だけど、頑張ればもっと早くなるような気がする。
気になったこと
少し気になったのが、Python標準のcmpを使ったとき若干の差があるみたい。(関数呼び出しでオーバーヘッド起こしてる?)
If 文分岐
[yasui@MacMini: ~/python/maptest][21:34] $ head -n 14 sort.py #!/usr/bin/env python # -*- coding: utf_8 -*- import sys import os def compare (x,y): xm = x[0] ym = y[0] xh = xm[xm.rindex('@')+1:].upper() yh = ym[ym.rindex('@')+1:].upper() # return cmp(xh, yh) if xh == yh: return 0 elif xh > yh: return 1 [yasui@MacMini: ~/python/maptest][21:34] $ /usr/bin/time ./sort.py random.cvs | tail -0 1.21 real 1.16 user 0.03 sys [yasui@MacMini: ~/python/maptest][21:34] $ /usr/bin/time ./sort.py random.cvs | tail -0 1.21 real 1.17 user 0.03 sys [yasui@MacMini: ~/python/maptest][21:34] $ /usr/bin/time ./sort.py random.cvs | tail -0 1.22 real 1.17 user 0.03 sys [yasui@MacMini: ~/python/maptest][21:34] $
cmp関数を使う
[yasui@MacMini: ~/python/maptest][21:35] $ head -n 14 sort.py #!/usr/bin/env python # -*- coding: utf_8 -*- import sys import os def compare (x,y): xm = x[0] ym = y[0] xh = xm[xm.rindex('@')+1:].upper() yh = ym[ym.rindex('@')+1:].upper() return cmp(xh, yh) if xh == yh: return 0 elif xh > yh: return 1 [yasui@MacMini: ~/python/maptest][21:35] $ /usr/bin/time ./sort.py random.cvs | tail -0 1.28 real 1.23 user 0.03 sys [yasui@MacMini: ~/python/maptest][21:35] $ /usr/bin/time ./sort.py random.cvs | tail -0 1.28 real 1.24 user 0.03 sys [yasui@MacMini: ~/python/maptest][21:35] $ /usr/bin/time ./sort.py random.cvs | tail -0 1.28 real 1.24 user 0.03 sys [yasui@MacMini: ~/python/maptest][21:35] $