はじめに

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

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

100本ノックのやっている環境としては、ubuntuに入れたAnaconda上のjupyter nootebookでやっています。
ファイルアクセスとinput回りで、別環境を考えたのですが何の問題もなくできました。
すごい。

解答後、答え合わせに他の人解答を見に行っているのですが、素人の言語処理100本ノック:まとめを見ていて。
linuxコマンドをしっかり調べていて、自分が恥ずかしくなりました。

指定がいるコマンドに関しては調べたのですが、wcやcutなどのオプションをあまり使用しなくても問題なく動作するコマンドに対して、調べることを怠りました。
勉強のためにやっているのに、怠慢でした。


10. 行数のカウント

行数をカウントせよ.確認にはwcコマンドを用いよ.

path = './hightemp.txt'
print(len(open(path).readlines()))
# wc hightemp.txt
# -lで行数のみの出力を得れる
# wc -l hightemp.txt
24

初めはwith asで書こうと考えていましたが、調べたら1行で書いている人がいたので書いてみました。

with open(path) as f:
    print(len(f.readlines()))

11. タブをスペースに置換

タブ1文字につきスペース1文字に置換せよ.確認にはsedコマンド,trコマンド,もしくはexpandコマンドを用いよ.

path = './hightemp.txt'
print(open(path).read().replace('\t', ' '))
# expand --tabs=1 hightemp.txt
# sed 's/\t/ /g' hightemp.txt
# cat hightemp.txt | tr '\t' ' '
高知県 江川崎 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

いつもreplaceを使用しているので、何も考えずreplaceを使用しました。
明日次の問題をやる前に調べます。

12. 1列目をcol1.txtに,2列目をcol2.txtに保存

各行の1列目だけを抜き出したものをcol1.txtに,2列目だけを抜き出したものをcol2.txtとしてファイルに保存せよ.確認にはcutコマンドを用いよ.

path = 'hightemp.txt'
values = [line.split() for line in open(path)]
with open('col1.txt', 'w') as col1:
    col1.write('\n'.join(map(lambda x: x[0], values)))
with open('col2.txt', 'w') as col2:
    col2.write('\n'.join(map(lambda x: x[1], values)))
print(open('col1.txt').readlines())
print(open('col2.txt').readlines())
# cut col1.txt
# cut col2.txt
# ここは普通にまちがっています
# -f で列番号を指定して、指定列のみを抽出できる
# cut -f 1 hightemp.txt
# cut -f 2 hightemp.txt 

['高知県\n', '埼玉県\n', '岐阜県\n', '山形県\n', '山梨県\n', '和歌山県\n', '静岡県\n', '山梨県\n', '埼玉県\n', '群馬県\n', '群馬県\n', '愛知県\n', '千葉県\n', '静岡県\n', '愛媛県\n', '山形県\n', '岐阜県\n', '群馬県\n', '千葉県\n', '埼玉県\n', '大阪府\n', '山梨県\n', '山形県\n', '愛知県']
['江川崎\n', '熊谷\n', '多治見\n', '山形\n', '甲府\n', 'かつらぎ\n', '天竜\n', '勝沼\n', '越谷\n', '館林\n', '上里見\n', '愛西\n', '牛久\n', '佐久間\n', '宇和島\n', '酒田\n', '美濃\n', '前橋\n', '茂原\n', '鳩山\n', '豊中\n', '大月\n', '鶴岡\n', '名古屋']

はじめは、writelinesで書き込んでいました。
改行が入力されないと知り、joinで改行コードを付け、writeで書き込むようにしました。
別のうまい書き方があるような気がしています。

13. col1.txtとcol2.txtをマージ

12で作ったcol1.txtとcol2.txtを結合し,元のファイルの1列目と2列目をタブ区切りで並べたテキストファイルを作成せよ.確認にはpasteコマンドを用いよ.

text = '\n'.join([i.strip() + '\t' + j.strip() for i, j in zip(open('col1.txt').readlines(), open('col2.txt').readlines())])
with open('col3.txt', 'w') as col3:
    col3.write(text)
print(open('col3.txt').read())
# paste -d '\t' col1.txt col2.txt
高知県   江川崎
埼玉県   熊谷
岐阜県   多治見
山形県   山形
山梨県   甲府
和歌山県    かつらぎ
静岡県   天竜
山梨県   勝沼
埼玉県   越谷
群馬県   館林
群馬県   上里見
愛知県   愛西
千葉県   牛久
静岡県   佐久間
愛媛県   宇和島
山形県   酒田
岐阜県   美濃
群馬県   前橋
千葉県   茂原
埼玉県   鳩山
大阪府   豊中
山梨県   大月
山形県   鶴岡
愛知県   名古屋

第一章の問題で使用したzipを使って結合しました。
これも別のうまいやり方があるような気がします。

14. 先頭からN行を出力

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

n = input('n line?')
if n.isdigit():
    n = int(n)
    print(''.join(open('hightemp.txt').readlines()[:n]))
# head -n 3 hightemp.txt
n line?3
高知県   江川崎   41  2013-08-12
埼玉県   熊谷  40.9    2007-08-16
岐阜県   多治見   40.9    2007-08-16

inputとreadlinesからの取得で作成しました。
初めは内包表記でループさせていましたが、調べているとreadlinesで指定した方が簡単に書けることを知り、指定する形にしました。
検索途中で、linecacheというものを発見しましたが今回は見送りました。


また今回のデータは、tsvなのでcsvのライブラリを使う手もあったのかなと考えました。
ですが、長くなりそうなので使いませんでした。

風呂プログラミングいいけど、湯が冷める。
冬はきついのかな。
なにかないかな。

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.