challenge 条件を満たす行を取り除く

ファイルから1行ずつ読み込み、"#"で始まる行だけを取り除いてファイルに出力するコードを書いてください。

サンプル入力

hello!
# remove this
 # don't remove this
bye!
サンプル出力
hello!
 # don't remove this
bye!

Posted feedbacks - Python


	
1
2
import fileinput
map(open("out.txt", "w").write, filter(lambda v: not v.startswith("#"), fileinput.input()))

ファイルの入出力はリダイレクションを利用。
Pythonのリストは遅延評価しないので、その場で評価され中身が実行される。
1
2
import sys
[l.startswith('#') or sys.stdout.write(l) for l in sys.stdin]

正規表現でやろうとしたけど、うまくいかなかった。 行頭を拾うのってどうすればいいんだっけ?
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# -*- coding: utf-8 -*-

infile = open("intext.txt", "r")
s = infile.read()
infile.close()

outfile = open("outtext.txt", "w")

for x in s.splitlines():
    if x[0] != "#":
        outfile.write(x + "\n")

outfile.close()

何気にwith文。多分Python2.5以降限定。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
from __future__ import with_statement
import sys

def convert(input, output):
    with open(output, "w") as io:
        for line in open(input):
            if not line.startswith("#"):
                io.write(line)

if __name__ == '__main__':
    convert(sys.argv[1], sys.argv[2])

行頭は^。 処理の中身を想像すると、正規表現内で否定を拾うより、ifの否定でやったほうが効率が良い気がする。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# -*- coding: utf-8 -*-
import re

infile = open("intext.txt", "r")
s = infile.read()
infile.close()

outfile = open("outtext.txt", "w")

for x in s.splitlines():
    if re.compile("^[^#]").search(x):
        outfile.write(x + "\n")

outfile.close()

なんでマイナス評価付いてるんだろう~
と思ったけど、プラス評価するほどでもないので評価はスルーで。

・readしてsplitしなくてもfileオブジェクトはイテレータ
・正規表現のコンパイルは重い処理なのでループの外へ

頭にシャープがあるかないかだけだから
正規表現を使うまでもない気もするけれど。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import re

infile = file("tmp.txt")
outfile = file("tmpout.txt", "w")
pat = re.compile("^[^#]")

for line in infile:
    if pat.match(line):
        outfile.write(line)

infile.close()
outfile.close()

ゆるせるワンライナー。
・ジェネレーター内包表現でコメント行を捨てる
・ファイルを変数に代入しないのでcloseはGC時に自動的に
1
2
3
4
5
file("tmpout.txt", "w").write(
    "".join(
        line
        for line in file("tmp.txt")
        if line[0] != "#"))

ゆるせないワンライナー

・リスト内包表現で副作用のある関数を呼ぶのは嫌い
 ・素直にfor文で書いた方がいい
1
2
3
[file("tmpout.txt", "w").write(line)
 for line in file("tmp.txt")
 if line[0] != "#")]

Index

Feed

Other

Link

Pathtraq

loading...