5

この単純な問題を解決できず、朝のほとんどを無駄にしました。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])

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

4

4 に答える 4

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]
于 2012-10-04T14:39:00.407 に答える
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)
于 2012-10-04T14:37:50.393 に答える
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']]]
于 2012-10-04T14:43:39.513 に答える
-1
datasets = []
with open('example') as f:
    for line in f:
        if line and not line.startswith('#'):
            datasets.append(line.split())
于 2012-10-04T14:35:17.030 に答える