【问题标题】:Using a for loop to add a new line to a table: python使用 for 循环向表中添加新行:python
【发布时间】:2020-08-12 20:59:46
【问题描述】:

在通过 DNA 序列搜索两个正则表达式后,我正在尝试创建一个 .bed 文件。理想情况下,我想生成一个制表符分隔的文件,其中包含序列描述、第一个正则表达式的开始位置和第二个正则表达式的结束位置。我知道正则表达式部分有效,它只是创建了我正在努力解决的 \t 分隔文件。

我希望我可以打开/创建一个文件,并为包含此信息的 for loop 的每次迭代打印一个新行,如下所示:

with open("Mimp_hits.bed", "a+") as file_object:
    for line in file_object:
        print(f'{sequence.description}\t{h.start()}\t{h_rc.end()}')
file_object.close()

但这似乎不起作用(创建空文件)。我也尝试过使用file_object.write,但这同样会创建一个空文件。

这是我拥有的所有代码,包括搜索正则表达式:

import re, sys

from Bio import SeqIO
from Bio.SeqRecord import SeqRecord

infile = sys.argv[1]

for sequence in SeqIO.parse(infile, "fasta"):
    hit = re.finditer(r"CAGTGGG..GCAA[TA]AA", str(sequence.seq))
    mimp_length = 400
    for h in hit:
        h_start = h.start()
        hit_rc = re.finditer(r"TT[TA]TTGC..CCCACTG", str(sequence.seq))
        for h_rc in hit_rc:
            h_rc_end = h_rc.end()
            length = h_rc_end - h_start
            if length > 0:
                if length < mimp_length:
                    with open("Mimp_hits.bed", "a+") as file_object:
                        for line in file_object:
                            print(sequence.description, h.start(), h_rc.end())
                    file_object.close()

这是所需的输出:

Focub_II5_mimp_1__contig_1.16(656599:656809)    2   208
Focub_II5_mimp_2__contig_1.47(41315:41540)  2   223
Focub_II5_mimp_3__contig_1.65(13656:13882)  2   224
Focub_II5_mimp_4__contig_1.70(61591:61809)  2   216

这是示例输入:

>Focub_II5_mimp_1__contig_1.16(656599:656809)
TACAGTGGGATGCAAAAAGTATTCGCAGGTGTGTAGAGAGATTTGTTGCTCGGAAGCTAGTTAGGTGTAGCTTGTCAGGTTCTCAGTACCCTATATTACACCGAGATCAGCGGGATAATCTAGTCTCGAGTACATAAGCTAAGTTAAGCTACTAACTAGCGCAGCTGACACAACTTACACACCTGCAAATACTTTTTGCATCCCACTGTA
>Focub_II5_mimp_2__contig_1.47(41315:41540)
TACAGTGGGAGGCAATAAGTATGAATACCGGGCGTGTATTGTTTTCTGCCGCTAGCCCATTTTAACAGCTAGAGTGTGTATATTAACCTCACACATAGCTATCTCTTATACTAATTGGTTAGGGAAAACCTCTAACCAGGATTAGGAGTCAACATAGCTTGTTTTAGGCTAAGAGGTGTGTGTCAGTACACCAAAGGGTATTCATACTTATTGCCCCCCACTGTA
>Focub_II5_mimp_3__contig_1.65(13656:13882)
TACAGTGGGAGGCAATAAGTATGAATACCGGGCGTGTATTGTTTTTCTGCCGCTAGCCTATTTTAATAGTTAGAGTGTGCATATTAACCTCACACATAGCTATCTTATATACTAATCGGTTAGGGAAAACCTCTAACCAGGATTAGGAGTCAACATAGCTTCTTTTAGGCTAAGAGGTGTGTGTCAGTACACCAAAGGGTATTCATACTTATTGCCCCCCACTGTA
>Focub_II5_mimp_4__contig_1.70(61591:61809)
TACAGTGGGATGCAATAAGTTTGAATGCAGGCTGAAGTACCAGCTGTTGTAATCTAGCTCCTGTATACAACGCTTTAGCTTGATAAAGTAAGCGCTAAGCTGTATCAGGCAAAAGGCTATCCCGATTGGGGTATTGCTACGTAGGGAACTGGTCTTACCTTGGTTAGTCAGTGAATGTGTACTTGAGTTTGGATTCAAACTTATTGCATCCCACTGTA

有人可以帮忙吗?

谢谢你:)

【问题讨论】:

  • 您正在为a+ 打开文件,因为您打算附加到它,但随后您对其进行了迭代?你的意图是什么?
  • 输入:sequence.description、h.start()、h_rc.end() 在搜索正则表达式时被识别。如果我在 file_object: 循环中的 for 行之外使用它,它会打印所需的输出。
  • Tadhg McDonald-Jensen,我相信我需要对其进行迭代以创建新行。这是不必要的吗?
  • 如果您的意图是在文件中添加一行,那么只需执行 print(..., file=file_object) 将行写入文件(不循环文件),如果这是所需的行为,我可以发布回答更详细。
  • using: print(sequence.description, h.start(), h_rc.end(), file=file_object) 没有循环确实提供了所需的输出!谢谢,我如何确保它是制表符分隔的?此外,如果您愿意,将非常感谢您提供更详细的答案。谢谢

标签: python file


【解决方案1】:

要向文件中写入一行,您可以执行以下操作:

with open("file.txt", "a") as f:
    print("new line", file=f)

如果你想要标签分隔,你也可以添加sep="\t",这就是为什么python 3制作print a function所以你可以使用sependfileflush关键字参数。 :)

打开文件进行追加意味着文件指针从文件末尾开始,这意味着写入文件不会覆盖任何数据(附加到文件末尾)并迭代它(或以其他方式从文件中读取)它)不会像你已经到达文件末尾那样给出任何东西。

因此,您只需将单行写入文件,而不是遍历文件的行:

                with open("Mimp_hits.bed", "a") as file_object:
                    print(sequence.description, h.start(), h_rc.end(), file=file_object)

您也可以考虑只在循环开始附近打开文件,因为打开一次并多次写入比多次打开更有效,而且 with 块会自动关闭文件,因此无需显式执行此操作。

【讨论】:

  • 我不知道 printfile 参数 - 这非常方便,谢谢。
  • 太棒了,谢谢。我已经修改了我的代码,它现在工作得很好。我可能应该用谷歌搜索这个或创建一个新帖子......但是当我有你时,我想知道是否有一种方法可以设置一个变量来命名文件?例如“{infile}_mimp_hits.bed”。我刚刚尝试过,但它实际上将输出文件命名为 {infile}_mimp_hits.bed,而不是说 input.fasta_mimp_hits.bed。
  • 如果你使用 python 3.7 或更高版本,你可以use an f-string,所以f"{infile}_mimp_hits.bed",早期版本你会使用"{}_mimp_hits.bed".format(infile),或者因为infile只是一个字符串,所以infile + "_mimp_hits.bed"也可以。
【解决方案2】:

您正试图以“a+”模式打开文件,并循环其中的行(这将找不到任何内容,因为当您这样做时文件位于末尾)。在任何情况下,如果这只是一个输出文件,那么您可以在“a”模式下打开它以附加到它。

可能您只想打开文件一次以进行追加,然后在 with 语句中执行主循环,当您想要将字符串实际追加到文件时使用 file_object.write(...)。请注意,使用此 with 构造时不需要 file_object.close()

with open("Mimp_hits.bed", "a") as file_object:
    for sequence in SeqIO.parse(infile, "fasta"):
        # ... etc per original code ...
                    if length < mimp_length:
                        file_object.write("{}\t{}\t{}\n".format(
                                sequence.description, h.start(), h_rc.end()))

【讨论】:

  • 刚注意到它要求制表符分隔的输出,所以我编辑它以使用\t
  • 感谢您的回复,我不知道“a+”和“a”模式之间的区别:)
  • @Jpike 带有“+”的各种模式是为读取和写入而打开的文件的不同变体。请参阅访问模式列表,例如stackabuse.com/file-handling-in-python
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多