100本ノック セット1
100本ノックを課題としてやったのでそのメモです。
東北大学の乾・岡崎研究室のサイトで公開されている、言語処理100本ノックのメモです。問題の詳細はサイトをご覧ください。
第1セット
(1) 行数をカウント。
#!usr/bin/env python3
# -*- coding: utf-8 -*-
i = sum(1 for line in open('address.txt'))
print(i)
for line in open('address.txt')で勝手に一行ずつ読んでくれます。
コマンド wc -l address.txt
(2) タブをスペースに置換。
# -*- coding: utf-8 -*-
src = open('address.txt')
data1 = src.read() #ファイル終端まで全て読んだデータを返す
src.close()
dst = data1.replace('\t', ' ')
print(dst)
\tがタブを表しています。
コマンド expand -1 address.txt
(3) 各行の1列目だけを抜き出したものをcol1.txtに,2列目だけを抜き出したものをcol2.txtとして保存
#!usr/bin/env python3
# -*- coding: utf-8 -*-
f = open('col1.txt', 'w') # 書き込みモードで開く
ff = open('col2.txt', 'w') # 書き込みモードで開く
for line in open('address.txt',"r"):
a=line.split('\t')
f.write(a[0]+'\n')
ff.write(a[1])
f.close()
ff.close()
split('\t')でタブで区切ることができます。 そしてfor line in open('address.txt',"r")で一行ずつ読み込み一列目a[0]をcol1.txtに二列目a[1]をcol2.txt書き込んだ。
コマンド
cut -f1 address.txt
cut -f2 address.txt
(4) (3)で作ったcol1.txtとcol2.txtを結合し,元のタブ区切りテキストを復元
#!usr/bin/env python3
# -*- coding: utf-8 -*-
src1 = open('col1.txt')
src2 = open('col2.txt')
data1 = src1.read() # ファイル終端まで全て読んだデータを返す
data2 = src2.read()
dst1=data1.strip().split("\n")
dst2=data2.strip().split("\n")
src1.close()
src2.close()
fire=""
f = open('ttt.txt', 'w') # 書き込みモードで開く
for i in range(len(dst1)):
fire+=dst1[i]+"\t"+dst2[i]+"\n"
f.write(fire)
f.close()
stripでかっこの中がない場合、空白文字が除去されます。これでいらない空白がなくなります。
コマンド paste col1.txt col2.txt
(5)自然数Nをコマンドライン引数にとり,入力のうち先頭のN行だけ書き出す。
#!usr/bin/env python3
# -*- coding: utf-8 -*-
src = open('address.txt','r')
import sys
argvs = sys.argv # コマンドライン引数を格納したリストの取得
argc = len(argvs) # 引数の個数
if (argc != 2):
print ('変数名がおかしいです')
quit() # プログラムの終了
N = int(argvs[1])
f = open('result.txt','w')
for i in range(N):
line = src.readline() # 1行読み込む(改行文字も含まれる)
f.write(line)
f.close
src.close()
sys.argvでコマンドラインから引数を渡すことができます。端末にpython ○○.py N って書くやつです。引数は○○.pyを含めて2つなので引数の個数が2じゃなかったら終了します。ですのでargvs[1]がNにあたります。
コマンド head -n 5 address.txt
(6)自然数Nをコマンドライン引数にとり,入力のうち末尾のN行だけ書き出す。
#!usr/bin/env python3
# -*- coding: utf-8 -*-
src = open('address.txt','r')
data = src.read()
dst=data.strip().split('\n')
import sys
argvs = sys.argv # コマンドライン引数を格納したリストの取得
argc = len(argvs) # 引数の個数
if (argc != 2):
print ('変数名がおかしいです')
quit() # プログラムの終了
N = int(argvs[1])
f = open('result.txt','w')
a=0
for i in open('address.txt','r'):
a=a+1
for i in range(a-N,a,1):
f.write(dst[i]+'\n')
f.close()
src.close()
for i in open('address.txt','r')で一行ずつ読み込んでいくので、aが行数で数えられます。コマンドラインから取得したNでaを引くと末尾のN行の始まりの数字がわかりますので、そこからaまでを出力すると得られる。
コマンド -n 5 address.txt
(7)1コラム目の文字列の異なり数(種類数)
#!usr/bin/env python3
# -*- coding: utf-8 -*-
src = open('address.txt')
data1 = src.read() # ファイル終端まで全て読んだデータを返す
src.close()
dst=data1.strip().split('\n')
a=''
for i in range(0,len(dst)):
dst2=dst[i].strip().split('\t')
a+=dst2[0]+'\n' # 引数の文字列をファイルに書き込む
b=a.strip().split('\n')
il= list(set(b))
print(len(il))
setを使うことによって重複する要素を除外することができ、除外したものをlenで数えることで異なり数を得ます。
コマンド sort col1.txt | uniq | wc address.txt
もしくわ sort col1.txt | uniq | wc -l ???
(8)各行を2コラム目の辞書順にソート
# -*- coding: utf-8 -*-
List =
for i in open("address.txt","r"):
dst = i[:-1].split("\t")
List.append(dst)
List.sort(key=lambda x: x[1])
for j in List:
print(j[0],j[1])
[:-1]と書くことで終端から1文字目とすることができます。そしてタブで区切ったものをListに追加していき、ソートします。lamdaを使って関数を作りx[1]で2コラム目を指定。
コマンド sort -k 2 address.txt
(9) 各行を2コラム目,1コラム目の優先順位で辞書の逆順ソートしたもの
# -*- coding: utf-8 -*-
List =
for i in open("address.txt","r"):
dst = i[:-1].split("\t")
List.append(dst)
List.sort(key=lambda x: x[1], reverse=True)
for j in List:
print(j[0],j[1])
reverseのキーワードをTrueにすると降順になる。
コマンド sort -k 2 -r address.txt
(10) 各行の2コラム目の文字列の出現頻度を求め,出現頻度の高い順に並べる。
# -*- coding: utf-8 -*-
f = open('col2.txt')
data = f.read()
words = {}
for word in data.split():
words[word] = words.get(word, 0) + 1
d = [(v,k) for k,v in words.items()]
d.sort()
d.reverse()
for count, word in d:
print (count, word)
get(キー, 値)で、キーが登録されている場合は辞書オブジェクト[キー]を返し、+1をつけることによって重なっていたら1増やしていける。
http://www.freia.jp/taka/blog/356/
(10)は↑を参考にしました。こんな便利な方法があるのですね。
コマンド sort col2.txt | uniq -c | sort -r