in python 循环打印来自交替文件的行
in python loop print lines from alternating files
我正在尝试使用 python 在两个单独的文件中找到感兴趣的四行块,然后按受控顺序打印出其中一些行。下面是两个输入文件和所需输出文件的示例。请注意,Input.fasta 中的 DNA 序列与 Input.fastq 中的 DNA 序列不同,因为 .fasta 文件已被读取更正。
Input.fasta
>read1
AAAGGCTGT
>read2
AGTCTTTAT
>read3
CGTGCCGCT
Input.fastq
@read1
AAATGCTGT
+
'(''%$'))
@read2
AGTCTCTAT
+
&---+2010
@read3
AGTGTCGCT
+
0-23;:677
DesiredOutput.fastq
@read1
AAAGGCTGT
+
'(''%$'))
@read2
AGTCTTTAT
+
&---+2010
@read3
CGTGCCGCT
+
0-23;:677
基本上我需要顺序行"AAAGGCTGT",
"AGTCTTTAT" 和 "input.fasta" 中的 "CGTGCCGCT" 以及 "input.fastq" 中的所有其他行。这允许将质量信息恢复到读取更正的 .fasta 文件。
这是我最接近的失败尝试:
fastq = open(Input.fastq, "r")
fasta = open(Input.fasta, "r")
ReadIDs = []
IDs = []
with fastq as fq:
for line in fq:
if "read" in line:
ReadIDs.append(line)
print(line.strip())
for ID in ReadIDs:
IDs.append(ID[1:6])
with fasta as fa:
for line in fa:
if any(string in line for string in IDs):
print(next(fa).strip())
next(fq)
print(next(fq).strip())
print(next(fq).strip())
我想我 运行 遇到了麻烦,因为我试图在同一个循环中嵌套 "with" 对两个不同文件的调用。这会正确打印 read1 所需的行,但不会继续遍历其余行并引发错误 "ValueError: I/O operation on closed file"
我喜欢 @Chris_Rands 的 更适合小文件,但这里有一个解决方案,它只使用 Python 附带的电池,并且内存效率高。它假设 fasta 和 fastq 文件以相同的顺序包含相同数量的读取。
with open('Input.fasta') as fasta, open('Input.fastq') as fastq, open('DesiredOutput.fastq', 'w') as fo:
for i, line in enumerate(fastq):
if i % 4 == 1:
for j in range(2):
line = fasta.readline()
print(line, end='', file=fo)
我建议你使用 Biopython,这将为你省去很多麻烦,因为它为这些文件格式提供了很好的解析器,它不仅可以处理标准情况,还可以处理例如 multi-line fasta .
这里是一个用相应的fasta序列行替换fastq序列行的实现:
from Bio import SeqIO
fasta_dict = {record.id: record.seq for record in
SeqIO.parse('Input.fasta', 'fasta')}
def yield_records():
for record in SeqIO.parse('Input.fastq', 'fastq'):
record.seq = fasta_dict[record.id]
yield record
SeqIO.write(yield_records(), 'DesiredOutput.fastq', 'fastq')
如果您不想使用 headers 而只是依赖顺序,那么解决方案更简单且内存效率更高(只需确保记录的顺序和数量相同),无需先定义字典,只需一起遍历记录即可:
fasta_records = SeqIO.parse('Input.fasta', 'fasta')
fastq_records = SeqIO.parse('Input.fastq', 'fastq')
def yield_records():
for fasta_record, fastq_record in zip(fasta_records, fastq_records):
fastq_record.seq = fasta_record.seq
yield fastq_record
## Open the files (and close them after the 'with' block ends)
with open("Input.fastq", "r") as fq, open("Input.fasta", "r") as fa:
## Read in the Input.fastq file and save its content to a list
fastq = fq.readlines()
## Do the same for the Input.fasta file
fasta = fa.readlines()
## For every line in the Input.fastq file
for i in range(len(fastq)):
print(fastq[i]))
print(fasta[2 * i])
print(fasta[(2 * i) + 1])
我正在尝试使用 python 在两个单独的文件中找到感兴趣的四行块,然后按受控顺序打印出其中一些行。下面是两个输入文件和所需输出文件的示例。请注意,Input.fasta 中的 DNA 序列与 Input.fastq 中的 DNA 序列不同,因为 .fasta 文件已被读取更正。
Input.fasta
>read1
AAAGGCTGT
>read2
AGTCTTTAT
>read3
CGTGCCGCT
Input.fastq
@read1
AAATGCTGT
+
'(''%$'))
@read2
AGTCTCTAT
+
&---+2010
@read3
AGTGTCGCT
+
0-23;:677
DesiredOutput.fastq
@read1
AAAGGCTGT
+
'(''%$'))
@read2
AGTCTTTAT
+
&---+2010
@read3
CGTGCCGCT
+
0-23;:677
基本上我需要顺序行"AAAGGCTGT", "AGTCTTTAT" 和 "input.fasta" 中的 "CGTGCCGCT" 以及 "input.fastq" 中的所有其他行。这允许将质量信息恢复到读取更正的 .fasta 文件。
这是我最接近的失败尝试:
fastq = open(Input.fastq, "r")
fasta = open(Input.fasta, "r")
ReadIDs = []
IDs = []
with fastq as fq:
for line in fq:
if "read" in line:
ReadIDs.append(line)
print(line.strip())
for ID in ReadIDs:
IDs.append(ID[1:6])
with fasta as fa:
for line in fa:
if any(string in line for string in IDs):
print(next(fa).strip())
next(fq)
print(next(fq).strip())
print(next(fq).strip())
我想我 运行 遇到了麻烦,因为我试图在同一个循环中嵌套 "with" 对两个不同文件的调用。这会正确打印 read1 所需的行,但不会继续遍历其余行并引发错误 "ValueError: I/O operation on closed file"
我喜欢 @Chris_Rands 的
with open('Input.fasta') as fasta, open('Input.fastq') as fastq, open('DesiredOutput.fastq', 'w') as fo:
for i, line in enumerate(fastq):
if i % 4 == 1:
for j in range(2):
line = fasta.readline()
print(line, end='', file=fo)
我建议你使用 Biopython,这将为你省去很多麻烦,因为它为这些文件格式提供了很好的解析器,它不仅可以处理标准情况,还可以处理例如 multi-line fasta .
这里是一个用相应的fasta序列行替换fastq序列行的实现:
from Bio import SeqIO
fasta_dict = {record.id: record.seq for record in
SeqIO.parse('Input.fasta', 'fasta')}
def yield_records():
for record in SeqIO.parse('Input.fastq', 'fastq'):
record.seq = fasta_dict[record.id]
yield record
SeqIO.write(yield_records(), 'DesiredOutput.fastq', 'fastq')
如果您不想使用 headers 而只是依赖顺序,那么解决方案更简单且内存效率更高(只需确保记录的顺序和数量相同),无需先定义字典,只需一起遍历记录即可:
fasta_records = SeqIO.parse('Input.fasta', 'fasta')
fastq_records = SeqIO.parse('Input.fastq', 'fastq')
def yield_records():
for fasta_record, fastq_record in zip(fasta_records, fastq_records):
fastq_record.seq = fasta_record.seq
yield fastq_record
## Open the files (and close them after the 'with' block ends)
with open("Input.fastq", "r") as fq, open("Input.fasta", "r") as fa:
## Read in the Input.fastq file and save its content to a list
fastq = fq.readlines()
## Do the same for the Input.fasta file
fasta = fa.readlines()
## For every line in the Input.fastq file
for i in range(len(fastq)):
print(fastq[i]))
print(fasta[2 * i])
print(fasta[(2 * i) + 1])