3

名前付きファイルを読み取り、空の行、スペースのみを含む行、または最初の文字として#を含む行を削除して、残りの行を処理する最もPython的な方法は何ですか?すべてがメモリに簡単に収まると仮定します。

注:これを行うのは難しいことではありません-私が求めているのは、最もPython的な方法です。私はRubyとJavaをたくさん書いてきましたが、気分が悪くなりました。

これがストローマンです:

file_lines = [line.strip() for line in open(config_file, 'r').readlines() if len(line.strip()) > 0]
for line in file_lines:
  if line[0] == '#':
    continue
  # Do whatever with line here.

私は簡潔さに興味がありますが、読みにくくなるという犠牲を払うことはありません。

4

8 に答える 8

5

ジェネレーターは、このようなタスクに最適です。それらは読みやすく、関心の分離を完全に維持し、メモリの使用と時間の面で効率的です。

def RemoveComments(lines):
    for line in lines:
        if not line.strip().startswith('#'):
            yield line

def RemoveBlankLines(lines):
    for line in lines:
        if line.strip():
            yield line

これらをファイルに適用します。

filehandle = open('myfile', 'r')
for line in RemoveComments(RemoveBlankLines(filehandle)):
    Process(line)

この場合、2つのジェネレーターを1つにマージできることは明らかですが、構成可能性を示すために、それらを別々に残しました。

于 2010-02-02T06:03:18.723 に答える
3
lines = [r for r in open(thefile) if not r.isspace() and r[0] != '#']

文字列の.isspace()方法は、文字列が完全に空白であるかどうかをテストするための最善の方法len(r.strip()) == 0です。(ech;-)などのゆがみは必要ありません。

于 2010-02-02T06:03:32.260 に答える
2
for line in open("file"):
    sline=line.strip()
    if sline and not sline[0]=="#" :
       print line.strip()

出力

$ cat file
one
#
  #

two

three
$ ./python.py
one
two
three
于 2010-02-02T05:50:55.273 に答える
1

私はこれを使用します:

processed = [process(line.strip())
             for line in open(config_file, 'r')
             if line.strip() and not line.strip().startswith('#')]

私がここで見る唯一の醜さは、繰り返されるすべての剥ぎ取りです。それを取り除くと、関数が少し複雑になります。

processed = [process(line)
             for line in (line.strip() for line in open(config_file, 'r'))
             if line and not line.startswith('#')]
于 2010-02-02T05:50:09.833 に答える
1

これは説明と一致します。

空であるか、スペースのみを含むか、または最初の文字として#を含む行を削除してから、残りの行を処理します

したがって、スペースで開始または終了する行は、自由に通過します。

with open("config_file","r") as fp:
    data = (line for line in fp if line.strip() and not line.startswith("#"))
    for item in data:
        print repr(item)
于 2010-02-02T06:02:20.263 に答える
1

私はポール・ハンキンの考え方が好きですが、私はそれを別の方法で行います。

from itertools import ifilter, ifilterfalse, imap

with open(r'c:\temp\testfile.txt', 'rb') as f:
    s1 = ifilterfalse(str.isspace, f)
    s2 = ifilter(lambda x: not x.startswith('#'), s1)
    s3 = imap(str.rstrip, s2)
    print "\n".join(s3)

メモリ使用量が心配な場合は、ここで提案されているより明白なアプローチのいくつかを使用する代わりに、おそらくこの方法でのみ実行します。そしてiscomment、ラムダを削除する関数を定義するかもしれません。

于 2010-02-02T08:19:50.393 に答える
0

少し新しいイディオムを使用して(またはPython 2.5を使用してfrom __future__ import with)これを行うことができます。これには、安全にクリーンアップできるという利点がありますが、非常に簡潔です。

with file('file.txt') as fp:
    for line in fp:
        line = line.strip()
        if not line or line[0] == '#':
            continue

        # rest of processing here

最初に行を削除すると、「#」のチェックは、単に「最初の文字」としてではなく、最初の非空白としての行を実際に拒否することに注意してください。あなたがそれについて厳格であるならば、修正するのに十分簡単です。

于 2010-02-02T06:05:25.237 に答える
0

ファイルは小さいので、パフォーマンスは実際には問題ではありません。簡潔さよりも明確にするために行きます:

fp = open('file.txt')
for line in fp:
    line = line.strip()
    if line and not line.startswith('#'):
        # process
fp.close()

必要に応じて、これを関数でラップできます。

于 2010-02-02T05:54:15.973 に答える