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コラム目の辞書順にソート

#!usr/bin/env python3
# -*- 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コラム目の優先順位で辞書の逆順ソートしたもの

#!usr/bin/env python3
# -*- 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コラム目の文字列の出現頻度を求め,出現頻度の高い順に並べる。

#!usr/bin/env python3
# -*- 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