Python100本ノック(20/100)

## はじめに
Pythonを行き当たりばったりで触ってきたので
何処までPythonできているのかを見つめ直すために、[自然言語処理100本ノック](http://www.cl.ecei.tohoku.ac.jp/nlp100
)していきます。
python2ばっかり使っていましたので、慣れるためにpython3でやっていきます。

[Python100本ノック(15/100)](https://qiita.com/ikura1/items/c1c6eacff1e6323fffe0)の続きをやっていきます。

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

```python
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コマンドで実現せよ．

```python
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列目の文字列の種類（異なる文字列の集合）を求めよ．確認にはsort, uniqコマンドを用いよ．

```python
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コマンドを用いよ（この問題はコマンドで実行した時の結果と合わなくてもよい）．

```python
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コマンドを用いよ．


```python
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`には便利な物が多い。

---

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