使用python处理此文本文件的大多数pythonic方法

时间:2013-02-02 01:06:25

标签: python

我有一个包含测试数据的文本文件,如下所示:

hdr 1

hdr2

hdr3

data1

data2

data3

data1

data2

....

每一行之间都有一个空行。

我需要创建一个包含

的列表列表
[[hdr1,hdr2,hdr3],[data1,data2,data3],[data1,data2,...]

这样做的简洁,pythonic方法是什么?

3 个答案:

答案 0 :(得分:7)

假设你的数据总是在你的例子中的3个块中,你可以使用itertools,如果你传递相同的迭代器6次,那么你应该最终得到6个字段,其中3个是空行,其他3个你感兴趣的小组:

import itertools

arr = []
with open('input.txt') as f:
    for field1,blank1,field2,blank2,field3,blank3 in itertools.izip_longest(*[f]*6):
        arr.append([field1,field2,field3])

(灵感来自this post

编辑:您可能需要在字段上调用strip(),以便不包含任何额外的\ n,因此arr.append([field1.strip(),field2.strip(),field3.strip()])

答案 1 :(得分:3)

这只是Charles Menguy解决方案的简化版本,我只是将其作为答案添加,因为它很难作为评论阅读。但这是关键:

首先,使用itertools recipes中的grouper将文件分组为6行:

groups = grouper(6, f)

接下来,你可以通过切片来抛出所有其他行:

nonblank = [group[::2] for group in groups]

或者,通过明确过滤出空白行:

nonblank = [filter(bool, group) for group in groups]

如果您需要删除每一行,可以使用列表推导或map。一般来说,如果我不需要lambda / partial up一个新函数,我更喜欢map,而在这里我们不需要;它只是map(str.strip, group)

把它放在一起,这就是整个事情,作为一个单行(我觉得它仍然很可读):

with open('input.txt') as f:
    arr = [map(str.strip, group[::2]) for group in grouper(6, f)]

答案 2 :(得分:0)

不知道它是最好的解决方案还是pythonic有多少,但你只需使用正则表达式来解析文件的行:

import re

regex = re.compile(r'^(\w+)\s*(\d+)')
last_groups = None
group = []
data = []

with open('data.txt', 'r') as f:
    for line in f:
        match = regex.search(line)
        if match:
            if last_groups is None:
                last_groups = match.groups()

            if last_groups[0] == match.groups()[0] and \
                    int(last_groups[1]) <= int(match.groups()[1]):
                last_groups = match.groups()
                group.append(''.join(last_groups))
            else:
                data.append(group)
                last_groups = match.groups()
                group = [''.join(last_groups)]

if group:
    data.append(group)