Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Python中读取包含可变多行数据的文件_Python - Fatal编程技术网

如何在Python中读取包含可变多行数据的文件

如何在Python中读取包含可变多行数据的文件,python,Python,我有一个大约100Mb的文件,看起来像这样: #meta data 1 skadjflaskdjfasljdfalskdjfl sdkfjhasdlkgjhsdlkjghlaskdj asdhfk #meta data 2 jflaksdjflaksjdflkjasdlfjas ldaksjflkdsajlkdfj #meta data 3 alsdkjflasdjkfglalaskdjf data = [[#meta data 1, skadjflaskdjfasljdfalskdj

我有一个大约100Mb的文件,看起来像这样:

#meta data 1    
skadjflaskdjfasljdfalskdjfl
sdkfjhasdlkgjhsdlkjghlaskdj
asdhfk
#meta data 2
jflaksdjflaksjdflkjasdlfjas
ldaksjflkdsajlkdfj
#meta data 3
alsdkjflasdjkfglalaskdjf
data = [[#meta data 1, skadjflaskdjfasljdfalskdjflsdkfjhasdlkgjhsdlkjghlaskdjasdhfk],
       [#meta data 2, jflaksdjflaksjdflkjasdlfjasldaksjflkdsajlkdfj],
       [#meta data 3, alsdkjflasdjkfglalaskdjf]]
此文件包含一行元数据,这些元数据对应于几个仅包含字母数字字符的可变长度数据。将这些数据读入如下简单列表的最佳方式是:

#meta data 1    
skadjflaskdjfasljdfalskdjfl
sdkfjhasdlkgjhsdlkjghlaskdj
asdhfk
#meta data 2
jflaksdjflaksjdflkjasdlfjas
ldaksjflkdsajlkdfj
#meta data 3
alsdkjflasdjkfglalaskdjf
data = [[#meta data 1, skadjflaskdjfasljdfalskdjflsdkfjhasdlkgjhsdlkjghlaskdjasdhfk],
       [#meta data 2, jflaksdjflaksjdflkjasdlfjasldaksjflkdsajlkdfj],
       [#meta data 3, alsdkjflasdjkfglalaskdjf]]

我最初的想法是使用
read()
方法将整个文件读入内存,然后使用正则表达式将数据解析为所需的格式。有更好的更像蟒蛇的方式吗?所有元数据行都以八进制开头,所有数据行都是字母数字。谢谢

我猜是这样的:

result = []
for line in file.readlines():
    if line[0] == '#':
        result.append([line])
    else:
        if len(result[-1]) == 1:
            result[-1].append(line)
        else:
            result[-1][-1] += line
未测试。

提供了一种将行收集到组中的简便方法:

import itertools

data=[]
with open('data.txt','r') as f:
    for key,group in itertools.groupby(f,lambda line: line.startswith('#meta')):
        if key:
            meta=next(group).strip()
        else:
            lines=''.join(group).strip()
            data.append((meta,lines))
print(data)            
屈服

[('#meta data 1', 'skadjflaskdjfasljdfalskdjfl\nsdkfjhasdlkgjhsdlkjghlaskdj\nasdhfk'), ('#meta data 2', 'jflaksdjflaksjdflkjasdlfjas\nldaksjflkdsajlkdfj'), ('#meta data 3', 'alsdkjflasdjkfglalaskdjf')]

表情

itertools.groupby(f,lambda line: line.startswith('#meta'))
返回一个迭代器。它遍历
f
中的行,并在每行调用
lambda
函数。当遇到以
#meta
开头的行时,该函数返回
True
,否则返回
False

itertools.groupby
收集返回相同值的所有连续行

因此,以
#meta
开头的行被放置在它自己的组中,然后所有不以
#meta
开头的后续行被放置在下一个组中,依此类推


键是
lambda
函数的返回值。在这种情况下,它将是
True
False

我会保持简单,比如:

data = [] # result
lastmeta = None # the last metadata line seen
chunks = [] # lines since the last metadata line
for line in input:
    if line[0] == '#': # metadata
        if lastmeta: # need to flush data we've collected
            data.append((lastmeta, ''.join(chunks))
        lastmeta = line
    else:
        chunks.append(line)

我不知道这是否是最快的方式,但从我的头脑来看:

data = []
with open('input.file', 'r') as fp:
    for line in fp:
        line = line.strip()
        if line[0] == '#':
            data.append((line, []))
        else:
            data[-1][1].append(line)
data = [(X, ''.join(Y)) for X, Y in data]

哇,太棒了!我唯一有困难的是,我的输出给了我
[(False,'skadjflaskdjfasljdfalskdjfl\nsdkfjhasdlkjglaskdj\nasdhfk')…
我似乎不明白为什么我会得到一个布尔值,为什么它是False?!看起来你可能是在打印
键,而不是
meta
?你在使用
data.append吗((键,行)
?如果是这样,请更改
key
-->
meta
。谢谢,这是一个很酷的答案。我从来没有想过这样做。