Python 保存一个文本字符串,如果它是由不同的特定文本字符串进行的?

Python 保存一个文本字符串,如果它是由不同的特定文本字符串进行的?,python,python-3.x,fastq,Python,Python 3.x,Fastq,很抱歉标题不好,我不知道该怎么回答我的问题 我已经编写了一个脚本,可以从fastq文件(纯文本基因组读取文件)中提取数据。每第一行是一个标题,第二行是一个基本字符串-第三行和第四行是不需要的 filename = 'C0_GGCTAC_R1_no_adapter_trimming.fastq' new_filename = filename[:-9] + '_new.fastq' with open(filename) as f_obj: file_contents = f_obj.r

很抱歉标题不好,我不知道该怎么回答我的问题

我已经编写了一个脚本,可以从fastq文件(纯文本基因组读取文件)中提取数据。每第一行是一个标题,第二行是一个基本字符串-第三行和第四行是不需要的

filename = 'C0_GGCTAC_R1_no_adapter_trimming.fastq'
new_filename = filename[:-9] + '_new.fastq'

with open(filename) as f_obj:
    file_contents = f_obj.readlines()

extracted_lines = ''
line_count = 0

# Pull header and base lines
for line in file_contents:
    line_count += 1
    # Headers
    if line_count == 1:
        extracted_lines += line
    # Reads ending in A
    elif line_count == 2 and line[-2] == 'A':
        extracted_lines += line
    # Reads ending in G
    elif line_count == 2 and line[-2] == 'G':
        extracted_lines += line
    # Reset counter
    elif line_count == 4:
        line_count = 0

with open(new_filename, 'w') as f_obj:
    f_obj.write(extracted_lines)
print(new_filename + " was created.")
只要基数的读取以A或G结束,脚本就会提取每次读取的头和读取中的基数字符串。 输入文件的示例如下:

@HWI-D00461:137:C9H2FACXX:3:1101:1239:1968 1:N:0:GGCTAC
NTGTGTAATAGATTTTACTTTTGCCTTTAAGCCCAAGGTCCTGGACTTGAAACATCCAAGGGATGGAAAATGCCGTATAACAGGGTGGAAGAGAGATTTGA
+
#1=BDDFFHHHFHIJJJJJJJJJJJJJJJJJJJJJIJJIJJJJJHJIIJHGIJJJJJJIHJJBGHJHIIJJJHHHHFFFFEEEDD;?BACDDDA?@CDDDC
@HWI-D00461:137:C9H2FACXX:3:1101:1117:1968 1:N:0:GGCTAC
NAAAGTCTACCAATTATACTTAGTGTGAAGAGGTGGGAGTTAAATATGACTTCCATTAATAGTTTCATTGTTTGGAAAACAGAGGTAATTTTTGATACAGA
+
#1=DDDFDFHHHGHIIGJJJJHIJIHHDIHHIJGGEI@GFGHIHIJHEFHIIIIGIJGHHGECFGIDHGIHIIEGIIJHHEEFFF7?ACEECCBBDEDDDC
输出文件如下所示

@HWI-D00461:137:C9H2FACXX:3:1101:1117:1968 1:N:0:GGCTAC
NAAAGTCTACCAATTATACTTAGTGTGAAGAGGTGGGAGTTAAATATGACTTCCATTAATAGTTTCATTGTTTGGAAAACAGAGGTAATTTTTGATACAGA
@HWI-D00461:137:C9H2FACXX:3:1101:1200:1972 1:N:0:GGCTAC
@HWI-D00461:137:C9H2FACXX:3:1101:1087:1973 1:N:0:GGCTAC
NTAATCCAACTAACTAAAAATAAAAAGATTCAAATAGGTACAGAAAACAATGAAGGTGTAGAGGTGAGAAATCAACAGGATGTTCAGAAGCCTGTGTATGA
尽管它包含了所需的所有数据,但它会提取出每一个标题行(以“@”开头),这是不必要的


如果代码是由以a或G结尾的一串基进行的,我如何修改代码以仅拉出标题行?

问题是您要为每个记录添加id,而不仅仅是为您感兴趣的记录添加id。快速解决方案是将id保留在变量中,并仅在必要时添加它:

filename = 'C0_GGCTAC_R1_no_adapter_trimming.fastq'
new_filename = filename[:-9] + '_new.fastq'

with open(filename) as f_obj:
    file_contents = f_obj.readlines()

extracted_lines = ''
line_count = 0

# Pull header and base lines
for line in file_contents:
    line_count += 1
    # Headers
    if line_count == 1:
        id_string = line
    # Reads ending in A
    elif line_count == 2 and line[-2] == 'A':
        extracted_lines += id_string
        extracted_lines += line
    # Reads ending in G
    elif line_count == 2 and line[-2] == 'G':
        extracted_lines += id_string
        extracted_lines += line
    # Reset counter
    elif line_count == 4:
        line_count = 0

with open(new_filename, 'w') as f_obj:
    f_obj.write(extracted_lines)
print(new_filename + " was created.")
我还必须说,代码效率不高,特别是在内存使用方面:您正在(通常)将一个非常大的文件读入内存,但一次只需要一条记录

次要问题是,您的条件可以压缩,您可以使用模来了解您所处的线型:

filename = 'C0_GGCTAC_R1_no_adapter_trimming.fastq'
new_filename = filename[:-9] + '_new.fastq'

with open(filename) as in_f_obj, open(new_filename, 'w') as out_f_obj:
    # Process the file
    line_count = 0
    for line in in_f_obj:
        line_count += 1

        # Extract the information for each record
        if line_count % 4 == 1:
            id_string = line
        elif line_count % 4 == 2:
            seq = line
        elif line_count % 4 == 3:
            extra = line
        elif line_count % 4 == 4:
            # Last part of the record. Here we have all the information
            # and we can decide if we want to output something
            # and what we want to output
            qual = line
            if seq[-2] == 'A' or seq[-2] == 'G'
                out_f_obj.write(id_string)
                out_f_obj.write(seq)

print(new_filename + " was created.")
在这段代码中,您只在内存中保留一条记录。
line\u count
变量包含处理的实际行数,并且您拥有来自输入的所有数据,因此您可以很容易地在以后更改输出

我会添加一个额外的细节,我会在每一行中去掉换行符,并在写作时添加它(如果需要):

# Extract the information for each record
if line_count % 4 == 1:
    id_string = line.rstrip()
elif line_count % 4 == 2:
    seq = line.rstrip()
elif line_count % 4 == 3:
    extra = line.rstrip()
elif line_count % 4 == 4:
    # Last part of the record. Here we have all the information
    # and we can decide if we want to output something
    # and what we want to output
    qual = line.rstrip()
    if seq[-1] == 'A' or seq[-1] == 'G'
        out_f_obj.write("{}\n{}\n".format(id_string, seq))

通过这种方式,您的数据是干净的,输入文件中没有新行格式。

我认为用4行步骤而不是单行来遍历文件会使您的任务更容易。至少假设始终存在4条相互关联的线路。然后,您可以在附加相应的标题行之前过滤所需的基数,例如:

extracted_lines = []
for i in range(0, len(file_contents), 4):
    header, bases, comment1, comment2 = file_contents[i:i+4]
    if bases[-1] in ["A", "G"]:
        extracted_lines.append(header)
        extracted_lines.append(bases)

这是一个很大的帮助,谢谢!:)有几件事,使用youre代码,我仍然有一个问题,不必要的头在哪里被写入,所以在每个elif循环的末尾,头被写入,我清除了变量。这给了我想要的输出。删除file\u contents变量后,我的代码运行得更快!不必要的标题还在吗?这没有意义,只需看看代码:每次添加头时,也会添加相应的序列。没有空间放置单独的标题:-?