【问题标题】:Read a text file into python by splitting the file into list items according to a set of characters通过根据一组字符将文件拆分为列表项,将文本文件读入 python
【发布时间】:2014-05-03 13:09:13
【问题描述】:

我有一个包含以下内容的纯文本文件:

@M00964: XXXXX
YYY
+
ZZZZ 
@M00964: XXXXX
YYY
+
ZZZZ
@M00964: XXXXX
YYY
+
ZZZZ

我想将其读入一个根据 ID 代码@M00964 拆分为项目的列表,即:

['@M00964: XXXXX
YYY
+
ZZZZ' 
'@M00964: XXXXX
YYY
+
ZZZZ'
'@M00964: XXXXX
YYY
+
ZZZZ']

我尝试过使用

in_file = open(fileName,"r")
sequences = in_file.read().split('@M00964')[1:]
in_file.close()

但这会删除 ID 序列 @M00964。有什么办法可以保留这个 ID 序列吗?

另外一个问题是有什么方法可以在列表中保留空格(而不是 /n 符号)。

我的总体目标是读入这组项目,以前 2 个项目为例,然后将它们写回保持所有原始格式的文本文件。

【问题讨论】:

  • .read() 读取 1 行。尝试使用读取所有行的.readlines(),然后拆分'\n'
  • 您能否详细说明“在列表中保留空白(而不是具有 \n 符号)”的含义? \n 只是“换行符”的简写,即空格。
  • 一个项目是什么样的?您上面的示例列表只有 1 项。
  • 看起来像 FASTQ,其中一条记录总是 4 行。如果您想要前 2 条记录,只需打印前 2*4 行。
  • @fredtantini Err,我认为您需要检查documentation。 Read 接受一个大小参数,如果没有,则读取整个文件

标签: python list readfile splice dna-sequence


【解决方案1】:

如果您的文件很大并且您不想将整个内容保存在内存中,您可以使用此辅助函数迭代单个记录:

def chunk_records(filepath)
    with open(filepath, 'r') as f:
        record = []
        for line in f:
            # could use regex for more complicated matching
            if line.startswith('@M00964') and record:
                yield ''.join(record)
                record = []
            else:
                record.append(line)
        if record:
            yield ''.join(record)

像这样使用它

for record in chunk_records('/your/filename.txt'):
    ...

或者如果你想把整个事情都放在内存中:

records = list(chunk_records('/your/filename.txt'))

【讨论】:

  • 文件中的换行符很重要,所以OP应该用'\n'而不是''加入它们
  • @Steven Rumbalski,谢谢你,我现在看看使用它。
  • @rmartinjak 你的意思是用'/n'替换上面代码中的''吗?
  • @martinjak:换行符永远不会被删除,因此它们不需要重新添加。当迭代文件中的行时,python 会留下以结尾的行。
  • 哦,确实,我完全忘记了
【解决方案2】:

具体到您的示例,您不能只执行以下操作:

in_file = open(fileName, 'r')
file = in_file.readlines()

new_list = [''.join(file[i*4:(i+1)*4]) for i in range(int(len(file)/4))]
list_no_n = [item.replace('\n','') for item in new_list]

print new_list
print list_no_n

[扩展形式]

new_list = []
for i in range(int(len(file)/4)): #Iterates through 1/4 of the length of the file lines.
                                  #This is because we will be dealing in groups of 4 lines
    new_list.append(''.join(file[i*4:(i+1)*4])) #Joins four lines together into a string and adds it to the new_list

[写入新文件]

write_list = ''.join(new_list).split('\n')
output_file = open(filename, 'w')
output_file.writelines(write_list)

【讨论】:

  • 嗨,对不起,我上个月才学python,你能解释一下这段代码的实际作用吗?谢谢你
  • @user3460300,代码将每四行组合在一起并将它们连接成一个字符串。然后它将四行一组并将它们组合成一个列表。我将更新我的答案以显示我正在做的事情的扩展形式。
  • @user3460300,没问题。祝你好运!
  • @user3460300,注意:我还创建了另一个名为 list_no_n 的变量。这与new_list 相同,但不包含任何\n 字符,因此可用于脚本内的数据处理。如果要将字符串写入另一个文件,可以使用原始的new_list 字符串及其保留的\n 字符,它将保持其格式。当然,你可以选择只写前两组数据,因为它是一个列表。
  • 因此,当我将前两个写回文本文件时,我将如何以保持文本文件中的格式而不是全部与 /n 字符一致的方式执行此操作?另外,谢谢你,我已经设法让第一个工作完美!
【解决方案3】:

只需在 @ 符号上拆分:

with open(fileName,"r") as in_file:
    sequences = in_file.read().replace("@","###@").split('###')

【讨论】:

  • 嗨,这仍然删除了@符号,理想情况下我想保留@M00946的整个ID
  • @Steven Rumbalski 如果文件很大,则 RAM 效率更高。我选择了最简单的解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-07-04
  • 2012-03-10
  • 1970-01-01
  • 2017-12-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多