更简化的方法来计算文件中的行数python

问题描述

我写这个是为了检索蛋白质登录号列表 (acc_list.txt) 的 FASTA 序列,每个都在一个新行上,并将它们写入一个 txt 文件 (prot_list)。

x=0
with open("acc_list.txt","r") as input:
    number = sum(1 for items in input) ###
with open("acc_list.txt","r") as input:
    with open ("prot_list.txt","w") as output:
        for acc in input:
            handle = Entrez.efetch(db="protein",id=acc,rettype="fasta")
            x+=1
            print("Dealing with",str(acc.strip()),str(x),"out of",str(number),sep=" ")
            output.write(handle.read())

这是一个很大的列表,所以倒数第二行让我了解进度。

如您所见,number = sum(1 for items in input) 给出了总行数,但我必须单独打开和关闭文件,因为如果我将其放在后一个 with 语句下,即

x=0
with open("acc_list.txt","w") as output:
        for acc in input:
            number = sum(1 for items in input) ###
            handle = Entrez.efetch(db="protein",sep=" ")
            output.write(handle.read())

它在对物品进行计数后停止并且不提供其他输出。 我猜这是因为 number = sum(1 for items in input) 遍历文件并结束迭代。

我很好奇是否有更有效的方法获取文件中的行数?我可以想象,如果我使用更大的列表,我的方法可能会出现问题。我看过较旧的答案,它们都涉及首先遍历文件

解决方法

从这里复制Is there a way to shallow copy an existing file-object ?

我已经结束了:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Mon Jun  7 11:40:04 2021

@author: Pietro


https://stackoverflow.com/questions/67850117/more-streamline-way-to-count-lines-in-file-python

"""


from Bio import Entrez

from itertools import tee




x=0
    
with open("acc_list.txt","r") as input:
    with open ("prot_list.txt","w") as output:  
        input1,input2 = tee(input,2)
    
    
        number = sum(1 for items in input2)-1
        print(number)
    
    
        for acc in input1:
            if acc.strip() != '': 
                try:
                    handle = Entrez.efetch(db="protein",id=acc,rettype="fasta")
                    x+=1
                    print("Dealing with",str(acc.strip()),str(x),"out of",str(number),sep=" ")
                    output.write(handle.read())
                except:
                    pass

不确定是更快还是您要找的,请告诉我们。

此外,我注意到在我的 acc_list.txt 文件的末尾,我总是将文件末尾的空行作为一个空的登录号,所以有点像 找到了一个巧妙的方法来抑制它

,

您可以让 grep 之类的现有工具来完成这项工作:

import subprocess

p = subprocess.run(['grep','-c','>','acc_list.txt'],check=True,capture_output=True,text=True)
seq_count = int(p.stdout)

在我的测试中,这比在 Python 中打开和计数要快,尤其是对于较大的文件。当最后一行不包含 > 时,计数 \n 而不是换行符也可以避免出现问题。