我正在尝试通过运行for循环来创建字典,其中它将描述细菌,关键是其DNA序列。唯一的问题是我的变量不能存储多个数据集,它只是覆盖了第一个数据集,因此只为我的字典提供了一个输出。
#reads a fasta file and seperates the description and dna sequences
for line in resistance_read:
if line.startswith(">"):
description = line
else:
sequence = line
#trying to get the output from the for loop and into the dictionary
bacteria_dict = {description:sequence}
输出:
line3description
dna3sequence
但是,通过以下代码,我可以获得所有输出
for line in resistance_read:
if line.startswith(">"):
print line
else:
print line
输出:
line1description
line2description
line3description
dna1sequence
dna2sequence
dna3sequence
答案 0 :(得分:2)
您不断地在迭代中覆盖变量的值。 sequence
和description
仅在迭代完成时保留最后的值。
相反,创建词典 first 并添加到词典中,作为一种更复杂的数据结构,它可以容纳更多数据。
然而,有一种更简单的方法......
首先,您需要打开文件并阅读这些行。为此,您可以使用with
context manager:
with open('file_path', 'r') as f:
# used strip() to remove '\n'
lines = [line.strip() for line in f]
现在所有行都在名为lines
的列表中,您希望在描述和序列之间创建映射。
如果描述行刚好在序列行上,请使用此slicing:
# take every other line (intervals of 2) starting from index 0
descriptions = lines[0::2]
sequences = lines[0::2]
现在使用zip
将它们压缩在一起,并从每对中创建一个映射:
result = dict(zip(descriptions, sequences))
如果是相反的方法,你可以使用相反的方法:
result = dict(zip(lines[1::2], lines[0::2]))
在您更新之后,似乎是这样做的方式,假设每个序列都有描述(确切地说),将行列表拆分为一半,然后压缩:
middle = len(lines) / 2
result = dict(zip(lines[:mid], lines[mid:]))
答案 1 :(得分:0)
根据您向我们展示的示例,您的文件格式似乎是N行描述,后面是N行DNA序列。这个答案假定每个描述或DNA序列是一行,并且有与描述一样多的序列。
如果你可以舒适地将所有东西都放在记忆中,那么我能想到的最简单的方法就是从上面的Reut Sharabani开始:
with open('file_path', 'r') as f:
# used strip() to remove '\n'
lines = [line.strip() for line in f]
拥有lines
后,您可以轻松创建两个列表,将其压缩并创建dict
:
descriptions = [line for line in lines if line.startswith('>')]
sequences = [line for line in lines if not line.startswith('>')]
result = dict(zip(sequences, descriptions))
但是,如果文件非常大,并且您不希望相当于读取其整个长度四次,则只需通过存储描述并将它们与序列进行匹配即可处理一次。当序列出现时。
result = {}
descriptions = []
with open('file_path', 'r') as f:
line = f.readline().strip()
while line.startswith('>'):
descriptions.append(line)
line = f.readline().strip()
result[line] = descriptions.pop(0)
for line in f:
result[line] = descriptions.pop(0)
当然,如果出现这种情况会遇到麻烦: