at_yasu's blog

ロード的なことを

頭の体操

例えば、「メールアドレス,名前」が一行ずつ入ったファイルがあったとする。

[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] $