LoginSignup
2
10

More than 5 years have passed since last update.

Python100本ノック(20/100)

Last updated at Posted at 2018-02-15

はじめに

Pythonを行き当たりばったりで触ってきたので
何処までPythonできているのかを見つめ直すために、自然言語処理100本ノックしていきます。
python2ばっかり使っていましたので、慣れるためにpython3でやっていきます。

Python100本ノック(15/100)の続きをやっていきます。


15. 末尾のN行を出力

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

n = input('n line?')
if n.isdigit():
    n = int(n)
    print(''.join(open('hightemp.txt').readlines()[-n:]))
    # tail -n 3 hightemp.txt
    # tail -3 hightemp.txt
n line?3
山梨県   大月  39.9    1990-07-19
山形県   鶴岡  39.9    1978-08-03
愛知県   名古屋   39.9    1942-08-02

readlinesで、配列を取得し[-n:]で後ろの指定行数を取得しました。

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

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

import math
n = input('n line?')
if n.isdigit():
    n = int(n)
    lines = open('hightemp.txt').readlines()
    # lines = list(range(12))
    # print(len(lines) / n)
    # print(math.ceil(len(lines) / n))
    # split -l 6 -d hightemp.txt hoge
    print('------\n'.join([''.join(lines[i * n:(i + 1) * n]) for i in range(0, math.ceil(len(lines) / n))]))
n line?6
高知県   江川崎   41  2013-08-12
埼玉県   熊谷  40.9    2007-08-16
岐阜県   多治見   40.9    2007-08-16
山形県   山形  40.8    1933-07-25
山梨県   甲府  40.7    2013-08-10
和歌山県    かつらぎ    40.6    1994-08-08
------
静岡県   天竜  40.6    1994-08-04
山梨県   勝沼  40.5    2013-08-10
埼玉県   越谷  40.4    2007-08-16
群馬県   館林  40.3    2007-08-16
群馬県   上里見   40.3    1998-07-04
愛知県   愛西  40.3    1994-08-05
------
千葉県   牛久  40.2    2004-07-20
静岡県   佐久間   40.2    2001-07-24
愛媛県   宇和島   40.2    1927-07-22
山形県   酒田  40.1    1978-08-03
岐阜県   美濃  40  2007-08-16
群馬県   前橋  40  2001-07-24
------
千葉県   茂原  39.9    2013-08-11
埼玉県   鳩山  39.9    1997-07-05
大阪府   豊中  39.9    1994-08-08
山梨県   大月  39.9    1990-07-19
山形県   鶴岡  39.9    1978-08-03
愛知県   名古屋   39.9    1942-08-02

readlinesで配列を取得し、指定行数で割り切れた数ループさせ分割しました。
割り切れない場合は、math.ceilで切り上げで対応しました。
15と同じく配列に引数を指定する形で、配列の分割を行いました。

UNIXコマントでは、split-l 6というオプションを付け行数分割を行いました。

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

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

kens = [line.split()[0] for line in open('hightemp.txt').readlines()]
# sorted(kens, key=lambda x: kens.count(x))
print(set(kens))
# print({k: kens.count(k) for k in set(kens)})
# ひどいコマンドな気がするけど、どうなんだ
# cut -f 1 hightemp.txt | sort | uniq -c
# cut -f 1 hightemp.txt | sort -t \t \u
{'静岡県', '山梨県', '大阪府', '千葉県', '山形県', '埼玉県', '愛知県', '愛媛県', '和歌山県', '高知県', '群馬県', '岐阜県'}

2章の前半と同じく、readlinesで取得し、splitで分解しました。
その後, setを使い重複の削除を行いました。

UNIXコマンドでは、cutで指定行のみを抽出した後、uniqかsortで重複をなくしました。

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

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

print(''.join(sorted(open('hightemp.txt').readlines(), key=lambda x: x.split()[2], reverse=True)))
# sort -k3 -r hightemp.txt
高知県   江川崎   41  2013-08-12
埼玉県   熊谷  40.9    2007-08-16
岐阜県   多治見   40.9    2007-08-16
山形県   山形  40.8    1933-07-25
山梨県   甲府  40.7    2013-08-10
和歌山県    かつらぎ    40.6    1994-08-08
静岡県   天竜  40.6    1994-08-04
山梨県   勝沼  40.5    2013-08-10
埼玉県   越谷  40.4    2007-08-16
群馬県   館林  40.3    2007-08-16
群馬県   上里見   40.3    1998-07-04
愛知県   愛西  40.3    1994-08-05
千葉県   牛久  40.2    2004-07-20
静岡県   佐久間   40.2    2001-07-24
愛媛県   宇和島   40.2    1927-07-22
山形県   酒田  40.1    1978-08-03
岐阜県   美濃  40  2007-08-16
群馬県   前橋  40  2001-07-24
千葉県   茂原  39.9    2013-08-11
埼玉県   鳩山  39.9    1997-07-05
大阪府   豊中  39.9    1994-08-08
山梨県   大月  39.9    1990-07-19
山形県   鶴岡  39.9    1978-08-03
愛知県   名古屋   39.9    1942-08-02

readlinesで取得後、sortedでソートしました。
ソートのキーには、lambda式を使い、'split'した後の3カラム目を指定しました。

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

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

kens = [line.split()[0] for line in open('hightemp.txt').readlines()]
print('\n'.join(sorted(set(kens), key=lambda x: kens.count(x), reverse=True)))
# cut -f 1 hightemp.txt | sort | uniq -c | sort -r

山梨県
山形県
埼玉県
群馬県
静岡県
千葉県
愛知県
岐阜県
大阪府
愛媛県
和歌山県
高知県

他の問題の応用で、sorted, set, lambdaを使ってソートを行いました。
ソートキーは、kensに何個あるかです。

from collections import Counter
kens = [line.split()[0] for line in open('hightemp.txt').readlines()]
ckens = Counter(kens)
print(ckens)
print(sorted(ckens, key=lambda x: ckens[x], revcerse=True))

Counterが単語と数の辞書形にしてくれるので、あとは順番変更するだけという形にもできました。
Counterは使ったことがなかったので、勉強になりました。
collectionsには便利な物が多い。


追い焚きグッズがあったけど、少し高めなのでアルミシート湯の上に引いたらどうなるか試してみます。

2
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
10