Python:读取文本文件并将文件拆分为列表变量,每个变量各有4行

时间:2018-06-20 15:03:27

标签: python

我有一个文本文件(fastq文件)。 该文件的格式为

1st line - ID
2nd Line - Sequence
3rd Line - something
4th Line - something else.

然后再次重复这4行。

例如:

1  @M9890393393
2 ATCTGTAAAA
3 +
4 FG%@ATAAAA
5  @M9890393394
6 ATGTCTATCC
7 +
8 AA%$$983089

我想做的是,分割此文件,以便可以按4行读取此文件。我可以制作一个列表,每个变量包含4行。在上面的示例中,我将列出带有2个变量的列表。

5 个答案:

答案 0 :(得分:2)

使用生成器,您可以定义一个惰性读取器,该读取器每次都会产生4个值的列表。

您可以如下所示耗尽或延迟迭代生成器。

import csv
from io import StringIO

mystr = StringIO("""1  @M9890393393
2 ATCTGTAAAA
3 +
4 FG%@ATAAAA
5  @M9890393394
6 ATGTCTATCC
7 +
8 AA%$$983089
""")

def gen():
    # replace mystr with open('file.csv', 'r')
    with mystr as fin:
        reader = csv.reader(fin, delimiter=' ',  skipinitialspace=True)
        res = []
        for line in reader:
            res.append(line[1])
            if len(res) == 4:
                yield res
                res = []

用尽发电机:

lines = list(gen())

print(lines)

[['@M9890393393', 'ATCTGTAAAA', '+', 'FG%@ATAAAA'],
 ['@M9890393394', 'ATGTCTATCC', '+', 'AA%$$983089']]

迭代生成器:

for line in gen():
    print(line)

['@M9890393393', 'ATCTGTAAAA', '+', 'FG%@ATAAAA']
['@M9890393394', 'ATGTCTATCC', '+', 'AA%$$983089']

答案 1 :(得分:1)

all 行读入单个行的列表,然后使用list-comp将四行的块分组在一起:

with open('your_file') as f:
    lines = f.read().strip().split('\n')

four_lines = [lines[i:i+4] for i in range(0,len(lines),4)]

在您的示例中,该值为four_lines

[
  [
    "1  @M9890393393",
    "2 ATCTGTAAAA",
    "3 +",
    "4 FG%@ATAAAA"
  ],
  [
    "5  @M9890393394",
    "6 ATGTCTATCC",
    "7 +",
    "8 AA%22209983089"
  ]
]

答案 2 :(得分:1)

如果只想将其分成4个,则可以使用:

In []:
with open('your_file') as f:
    result = list(zip(*[map(str.strip, f)]*4))   # Assumes Py3+ use iter(map(...)) in Py2
result

Out[]:
[('@M9890393393', 'ATCTGTAAAA', '+', 'FG%@ATAAAA'),
 ('@M9890393394', 'ATGTCTATCC', '+', 'AA%$$983089')]

为每个变量创建变量的想法通常没有多大意义,但是如果第一行包含要使用的ID,则dict可能有用:

In []:
with open('your_file') as f:
    result = {head: tail for head, *tail in zip(*[map(str.strip, f)]*4)}
result
Out[]:
{'@M9890393393': ['ATCTGTAAAA', '+', 'FG%@ATAAAA'],
 '@M9890393394': ['ATGTCTATCC', '+', 'AA%$$983089']}

对不起,假设示例中添加了行号,而不是部分数据集。您可以将zip()替换为以下数字(从@jpp的答案中借出):

from operator import itemgetter

zip(*[map(itemgetter(1), csv.reader(f, delimiter=' ', skipinitialspace=True))]*4)

答案 3 :(得分:1)

fastq格式易于解析,您可以在行的开头开始检查“ @”。那就是你的序列号。然后,您可以简单地追加接下来的3行,然后重新开始。如果质量得分行也以“ @”开头,则可能会出现一种“罕见”的问题情况。但是,即使这种情况也很容易发现,因为质量得分行始终位于“ +”行之后。

答案 4 :(得分:-1)

您可以使用下面的功能读取文件。

list = file.readlines()

一旦您读完文件,便可以使用嵌套循环来完成任务。