言語処理100本ノック 2015 第2章 15〜19

言語処理100本ノック 2015」の「第2章: UNIXコマンドの基礎」、15〜19。

15. 末尾のN行を出力

自然数Nをコマンドライン引数などの手段で受け取り,入力のうち末尾のN行だけを表示せよ.確認にはtailコマンドを用いよ.

listでFIFO的に追加して先頭を削除、という動きにしてみました。

import argparse


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('infile', type=argparse.FileType('r'))
    parser.add_argument('count', type=int)
    args = parser.parse_args()

    result = []
    for line in args.infile:
        result.append(line)

        if args.count < len(result):
            del result[0]

    for line in result:
        print(line, end='')


if __name__ == '__main__':
    main()

16. ファイルをN分割する

自然数Nをコマンドライン引数などの手段で受け取り,入力のファイルを行単位でN分割せよ.同様の処理をsplitコマンドで実現せよ.

綺麗に割り切れれば楽なのですが必ずしもそうではないので端数調整、あと分割後のサフィックス「aa」「ab」形式に合わせるためにちょっと変なことしています。

import argparse


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('n', type=int)
    parser.add_argument('infile', type=argparse.FileType('r'))
    parser.add_argument('prefix')
    args = parser.parse_args()

    lines = args.infile.readlines()
    lines_len = len(lines)
    c = lines_len // args.n
    adj = lines_len % args.n

    lines_list =  * adj +  * (args.n - adj)

    for i, line_count in enumerate(lines_list):
        filename = args.prefix + 'a' + chr(ord('a') + i)

        with open(filename, 'w') as f:
            f.writelines(lines[0:line_count])

        del lines[0:line_count]


if __name__ == '__main__':
    main()

17. 1列目の文字列の異なり

1列目の文字列の種類(異なる文字列の集合)を求めよ.確認にはsort, uniqコマンドを用いよ.

各行をsplitして先頭要素(1列目)のsetを作り、それを再度改行文字でjoinという実質1行コードです。

import argparse


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('infile', type=argparse.FileType('r'))
    args = parser.parse_args()

    print('\n'.join({x.split()[0] for x in args.infile}))


if __name__ == '__main__':
    main()

18. 各行を3コラム目の数値の降順にソート

各行を3コラム目の数値の逆順で整列せよ(注意: 各行の内容は変更せずに並び替えよ).確認にはsortコマンドを用いよ(この問題はコマンドで実行した時の結果と合わなくてもよい).

sortedでkeyとして3番目の要素を返すラムダ式を指定、逆順ということなのでreverse=Trueも指定。

import argparse


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('infile', type=argparse.FileType('r'))
    args = parser.parse_args()

    result = sorted([x for x in args.infile],
                    key=lambda x: x.split()[2], reverse=True)
    print(''.join(result))


if __name__ == '__main__':
    main()

19. 各行の1コラム目の文字列の出現頻度を求め,出現頻度の高い順に並べる

各行の1列目の文字列の出現頻度を求め,その高い順に並べて表示せよ.確認にはcut, uniq, sortコマンドを用いよ.

県ごとにカウント、それをlist化してソート…という作り。もっとシンプルに作れるような気はするんだけど…

import argparse


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('infile', type=argparse.FileType('r'))
    args = parser.parse_args()

    prefdict = dict()

    for line in args.infile:
        pref = line.split()[0]

        if pref in prefdict:
            prefdict[pref] += 1
        else:
            prefdict[pref] = 1

    result = sorted(prefdict.items(), key=lambda x: x[1], reverse=True)

    print('\n'.join([str(freq) + ' ' + pref for pref, freq in result]))


if __name__ == '__main__':
    main()

2章まで完了…

スポンサーリンク

フォローする

スポンサーリンク