2012-10-04 13 views
5

私の朝の大半はこの単純な問題を解決するのに無駄でした。 pythonを使用して、私は次のようになり、データファイルを解析する:Pythonのコメントブロックに基づいてテキストファイルを分割するにはどうしたらいいですか?

# This is an example comment line, it starts with a '#' character. 
# There can be a variable number of comments between each data set. 
# Comments "go with" the data set that comes after them. 
# The first data set starts on the next line: 
0.0 1.0 
1.0 2.0 
2.0 3.0 
3.0 4.0 

# Data sets are followed by variable amounts of white space. 
# The second data set starts after this comment 
5.0 6.0 
6.0 7.0 


# One more data set. 
7.0 8.0 
8.0 9.0 

私が欲しいのpythonコードはリストの要素として、それらを格納し、3の「ブロック」に上記の例を解析します。個々のコードブロック自体は、コメント行の有無にかかわらず、行のリストとして格納することができます。これを行うのが手作業です。

#! /usr/bin/env python 

# Read in data, seperate into rows_alldata 
f=open("example") 
rows = f.read().split('\n') 
f.close() 

# Do you haz teh codez? 
datasets=[] 
datasets.append(rows[0:8]) 
datasets.append(rows[9:13]) 
datasets.append(rows[15:18]) 

私は、可変数とデータセットの長さをサポートするより一般的なソリューションを探しています。私は、非パイソン様のループを構築したいくつかの大災害を試みました。私は彼らと私の質問を混乱させないのが最善だと思う。これは仕事であり、「宿題」ではありません。

+0

は常に設定されたデータが文字列として格納されますか? –

+0

データは生のテキストですが、最終的にはそれを解析して浮動小数点にします。 –

+0

あなたは何を知っていますか...もう一度見てみると、データセット間の空白ブロックに基づいて分割するのが最も簡単だと思います。 –

答えて

5

使用groupby

from itertools import groupby 

def contains_data(ln): 
    # just an example; there are smarter ways to do this 
    return ln[0] not in "#\n" 

with open("example") as f: 
    datasets = [[ln.split() for ln in group] 
       for has_data, group in groupby(f, contains_data) 
       if has_data] 
+0

これも完全に機能します。 –

+0

あなたの 'contains_data'実装では、普遍的な改行サポートモード – wim

+0

@wimでファイルを開くことができます:私はコメントを入れました。コメントや空行を正しく処理する方法は、OPのファイルによって異なります。空白などしか含まれていない行も解析する必要があります。 –

-1
datasets = [] 
with open('example') as f: 
    for line in f: 
     if line and not line.startswith('#'): 
      datasets.append(line.split()) 
+0

これは 'for line in f'でなければなりません。 –

+1

これはデータセットを分離しません。 @larsmans forループにもコロンがありません。 –

+1

-1は、オペレーションが望むものを実行しません。構文エラー、意味エラー –

3
datasets = [[]] 
with open('/tmp/spam.txt') as f: 
    for line in f: 
    if line.startswith('#'): 
     if datasets[-1] != []: 
     # we are in a new block 
     datasets.append([]) 
    else: 
     stripped_line = line.strip() 
     if stripped_line: 
     datasets[-1].append(stripped_line) 
+0

これはまさに私がしたいことです。 –

+1

嬉しいです。もしそこにnumpyがあるなら、 'np.loadtxt'を使ってフロートを簡単に解析することを検討することをお勧めします。 – wim

1
import pprint 

with open("test.txt") as fh: 
    codes = [] 
    codeblock = [] 

    for line in fh: 
     stripped_line = line.strip() 

     if not stripped_line: 
      continue 

     if stripped_line.startswith("#"): 
      if codeblock: 
       codes.append(codeblock) 
       codeblock = [] 

     else: 
      codeblock.append(stripped_line.split(" ")) 

    if codeblock: 
     codes.append(codeblock) 

pprint.pprint(codes) 

出力:

[[['0.0', '1.0'], ['1.0', '2.0'], ['2.0', '3.0'], ['3.0', '4.0']], 
[['5.0', '6.0'], ['6.0', '7.0']], 
[['7.0', '8.0'], ['8.0', '9.0']]] 
+0

他のソリューションほどエレガントではないとは思いますが、これも機能します。 –

関連する問題