使用python通过两个标识符(如开始和结束)从一个巨大的文本文件中提取行

使用python通过两个标识符(如开始和结束)从一个巨大的文本文件中提取行,python,python-2.7,Python,Python 2.7,我编写了一个函数,用于从大型文本文件中提取特定的文本块,示例文本如下所示: ATP(1):C39(3) - A:TYR(58):CD2(67) ATP(1):C39(3) - A:TYR(58):CE2(69) ATP(1):C59(6) - A:ILE(61):CD1(100) ATP(1):C59(6) - A:LYS(87):CE(344) Hydrogen bonds: Location of Donor | Sidechain/Backbone

我编写了一个函数,用于从大型文本文件中提取特定的文本块,示例文本如下所示:

 ATP(1):C39(3) - A:TYR(58):CD2(67)
     ATP(1):C39(3) - A:TYR(58):CE2(69)
     ATP(1):C59(6) - A:ILE(61):CD1(100)
     ATP(1):C59(6) - A:LYS(87):CE(344)

Hydrogen bonds:
    Location of Donor | Sidechain/Backbone | Secondary Structure | Count 
   -------------------|--------------------|---------------------|-------
          LIGAND      |      SIDECHAIN     |        OTHER        |   1   

         RECEPTOR     |      BACKBONE      |         BETA        |   1   

Raw data:
     ATP(1):O2A(9) - A:ILE(61):HN(93) - A:ILE(61):N(92)

Hydrophobic contacts (C-C):
    Sidechain/Backbone | Secondary Structure | Count 
   --------------------|---------------------|-------
         SIDECHAIN     |        OTHER        |   2   
         SIDECHAIN     |         BETA        |   23  

Raw data:
     ATP(1):C39(3) - A:TYR(58):CD2(67)
     ATP(1):C39(3) - A:TYR(58):CE2(69)
     ATP(1):C59(6) - A:ILE(61):CD1(100)
     ATP(1):C59(6) - A:LYS(87):CE(344)
     ATP(1):C4(23) - A:PHE(209):CD1(1562)
     ATP(1):C4(23) - A:PHE(209):CE1(1564)
     ATP(1):C2(26) - A:PHE(209):CD2(1563)
     ATP(1):C6(28) - A:PHE(209):CB(1560)
     ATP(1):C6(28) - A:PHE(209):CG(1561)
     ATP(1):C6(28) - A:PHE(209):CD1(1562)
     ATP(1):C6(28) - A:VAL(286):CG2(2266)

pi-pi stacking interactions:
     ATP(1):C8(30) - A:LYS(87):CG(342)
     ATP(1):C8(30) - A:GLU(159):CD(1066)
     ATP(1):C8(30) - A:PHE(209):CE1(1564)
我编写了一个函数来提取块:

from itertools import islice

def start_end_points(file_name):


    f = open(file_name)
    lines = f.readlines()

    for s, line in enumerate(lines):
        if "Hydrogen bonds:" in line:
            print s

    for e, line in enumerate(lines):
        if "pi-pi stacking interactions:" in line:
            print e

    print islice(lines, s, e) 

start_end_points("foo.txt")
有没有办法更有效地编写此代码?因为我想将此代码用作Web工具的一部分,所以代码的效率非常重要


谢谢。

您甚至不必将所有行保存到内存中

def start_end_points(file_name):
    with open(file_name) as f:
        found = False
        for line in f:
            if found or ("Hydrogen bonds:" in line):
                found = True
                print line
            if "pi-pi stacking interactions:" in line:
                break

start_end_points("foo.txt")
带有effective的
自动关闭文件,因此它非常高效和有用

请注意这两个选项-如果都是关于效率,请选择第一个选项

我建议
返回
ing行,而不是
打印
行-也许你会有额外的用途,然后你可以再次打印,而不是再次运行整个功能

def start_end_points(file_name):

    wanted_text = ""

    # USE this way -EFFICIENT!

    with open(file_name, "r") as f:
        found = False
        for line in f:
            if found:
                if "pi-pi stacking interactions:" in line:
                    break
                else:
                    wanted_text += line 
            if "Hydrogen bonds:" in line:
                wanted_text += line
                found = True



    # OR use this way *less efficient memory speaking*, but pythonic

    with open(file_name, "r") as f:
        all = f.read().split('\n')
        numbers = [i for i, line in enumerate(all) if "Hydrogen bonds:" in line or "pi-pi stacking interactions:" in line]
        wanted_text = all[numbers[0]:numbers[1]]


    # eventually, return:
    return wanted_text


data = start_end_points("foo.txt")

您甚至不必将所有行保存到内存中

def start_end_points(file_name):
    with open(file_name) as f:
        found = False
        for line in f:
            if found or ("Hydrogen bonds:" in line):
                found = True
                print line
            if "pi-pi stacking interactions:" in line:
                break

start_end_points("foo.txt")
带有
effective的
自动关闭文件,因此它非常高效和有用

请注意这两个选项-如果都是关于效率,请选择第一个选项

我建议
返回
ing行,而不是
打印
行-也许你会有额外的用途,然后你可以再次打印,而不是再次运行整个功能

def start_end_points(file_name):

    wanted_text = ""

    # USE this way -EFFICIENT!

    with open(file_name, "r") as f:
        found = False
        for line in f:
            if found:
                if "pi-pi stacking interactions:" in line:
                    break
                else:
                    wanted_text += line 
            if "Hydrogen bonds:" in line:
                wanted_text += line
                found = True



    # OR use this way *less efficient memory speaking*, but pythonic

    with open(file_name, "r") as f:
        all = f.read().split('\n')
        numbers = [i for i, line in enumerate(all) if "Hydrogen bonds:" in line or "pi-pi stacking interactions:" in line]
        wanted_text = all[numbers[0]:numbers[1]]


    # eventually, return:
    return wanted_text


data = start_end_points("foo.txt")

我认为这更有效,因为您可以迭代
f
,所以您可以保存这个列表转换
lines=f.readlines()
。此外,此代码仅通过数据执行一次(使用2个while循环),其中代码使用2个for循环,这两个循环都运行到文件末尾

from pprint import pprint


def start_end_points(file_name):

    f = open(file_name)

    single_line = next(f)

    while "Hydrogen bonds:" not in single_line:
        single_line = next(f)

    result = []

    while "pi-pi stacking interactions:" not in single_line:
        result.append(single_line.rstrip())
        single_line = next(f)


    f.close()

    pprint(result)
重要注意事项:打开文件后,您仍然可以修改它。因此,您在
while
循环中读取的行可能不是您打开
f
时想到的行

输出btw:

['Hydrogen bonds:',
 '    Location of Donor | Sidechain/Backbone | Secondary Structure | Count',
 '   -------------------|--------------------|---------------------|-------',
 '          LIGAND      |      SIDECHAIN     |        OTHER        |   1',
 '',
 '         RECEPTOR     |      BACKBONE      |         BETA        |   1',
 '',
 'Raw data:',
 '     ATP(1):O2A(9) - A:ILE(61):HN(93) - A:ILE(61):N(92)',
 '',
 'Hydrophobic contacts (C-C):',
 '    Sidechain/Backbone | Secondary Structure | Count',
 '   --------------------|---------------------|-------',
 '         SIDECHAIN     |        OTHER        |   2',
 '         SIDECHAIN     |         BETA        |   23',
 '',
 'Raw data:',
 '     ATP(1):C39(3) - A:TYR(58):CD2(67)',
 '     ATP(1):C39(3) - A:TYR(58):CE2(69)',
 '     ATP(1):C59(6) - A:ILE(61):CD1(100)',
 '     ATP(1):C59(6) - A:LYS(87):CE(344)',
 '     ATP(1):C4(23) - A:PHE(209):CD1(1562)',
 '     ATP(1):C4(23) - A:PHE(209):CE1(1564)',
 '     ATP(1):C2(26) - A:PHE(209):CD2(1563)',
 '     ATP(1):C6(28) - A:PHE(209):CB(1560)',
 '     ATP(1):C6(28) - A:PHE(209):CG(1561)',
 '     ATP(1):C6(28) - A:PHE(209):CD1(1562)',
 '     ATP(1):C6(28) - A:VAL(286):CG2(2266)',
 '']

我认为这更有效,因为您可以迭代
f
,所以您可以保存这个列表转换
lines=f.readlines()
。此外,此代码仅通过数据执行一次(使用2个while循环),其中代码使用2个for循环,这两个循环都运行到文件末尾

from pprint import pprint


def start_end_points(file_name):

    f = open(file_name)

    single_line = next(f)

    while "Hydrogen bonds:" not in single_line:
        single_line = next(f)

    result = []

    while "pi-pi stacking interactions:" not in single_line:
        result.append(single_line.rstrip())
        single_line = next(f)


    f.close()

    pprint(result)
重要注意事项:打开文件后,您仍然可以修改它。因此,您在
while
循环中读取的行可能不是您打开
f
时想到的行

输出btw:

['Hydrogen bonds:',
 '    Location of Donor | Sidechain/Backbone | Secondary Structure | Count',
 '   -------------------|--------------------|---------------------|-------',
 '          LIGAND      |      SIDECHAIN     |        OTHER        |   1',
 '',
 '         RECEPTOR     |      BACKBONE      |         BETA        |   1',
 '',
 'Raw data:',
 '     ATP(1):O2A(9) - A:ILE(61):HN(93) - A:ILE(61):N(92)',
 '',
 'Hydrophobic contacts (C-C):',
 '    Sidechain/Backbone | Secondary Structure | Count',
 '   --------------------|---------------------|-------',
 '         SIDECHAIN     |        OTHER        |   2',
 '         SIDECHAIN     |         BETA        |   23',
 '',
 'Raw data:',
 '     ATP(1):C39(3) - A:TYR(58):CD2(67)',
 '     ATP(1):C39(3) - A:TYR(58):CE2(69)',
 '     ATP(1):C59(6) - A:ILE(61):CD1(100)',
 '     ATP(1):C59(6) - A:LYS(87):CE(344)',
 '     ATP(1):C4(23) - A:PHE(209):CD1(1562)',
 '     ATP(1):C4(23) - A:PHE(209):CE1(1564)',
 '     ATP(1):C2(26) - A:PHE(209):CD2(1563)',
 '     ATP(1):C6(28) - A:PHE(209):CB(1560)',
 '     ATP(1):C6(28) - A:PHE(209):CG(1561)',
 '     ATP(1):C6(28) - A:PHE(209):CD1(1562)',
 '     ATP(1):C6(28) - A:VAL(286):CG2(2266)',
 '']

您没有理由将整个文件加载到内存中

def start_end_points(file_name):
    with open(file_name) as f:
        found = False
        for line in f:
            if found or ("Hydrogen bonds:" in line):
                found = True
                print line
            if "pi-pi stacking interactions:" in line:
                break

start_end_points("foo.txt")

这样,您在内存中只保留一个缓冲区,每行处理一次,并在到达pi后立即停止读取文件。。。行。

您没有理由将整个文件加载到内存中

def start_end_points(file_name):
    with open(file_name) as f:
        found = False
        for line in f:
            if found or ("Hydrogen bonds:" in line):
                found = True
                print line
            if "pi-pi stacking interactions:" in line:
                break

start_end_points("foo.txt")

这样,您在内存中只保留一个缓冲区,每行处理一次,并在到达pi后立即停止读取文件。。。行。

您到底想做什么?从包含氢键的线到包含π堆积相互作用的线,提取所有元素:?这些块可能在文件中发生多次,如果发生,您希望保留所有块吗?如果没有更多的信息,我只能说,在一个大文件上的
读线
不是内存效率高的…也许你可以使用linecache@SergeBallesta bot标识符是唯一的,并且恰好在一个文件中有一个标识符。顺便说一句,您的代码中有一个错误。
s
e
将在执行两个
for
循环后等于文件的长度。您可能需要
break
语句。您到底想做什么?从包含氢键的线到包含π堆积相互作用的线,提取所有元素:?这些块可能在文件中发生多次,如果发生,您希望保留所有块吗?如果没有更多的信息,我只能说,在一个大文件上的
读线
不是内存效率高的…也许你可以使用linecache@SergeBallesta bot标识符是唯一的,并且恰好在一个文件中有一个标识符。顺便说一句,您的代码中有一个错误。
s
e
将在执行两个
for
循环后等于文件的长度。您可能需要
break
语句。将
if found
条件放在第一位,将
elif
放在第二个条件下,不是更好吗。我认为这样可以避免一些检查。如果先找到
if
条件,然后将
elif
条件放在第二个条件,不是更好吗。我想这样可以避免一些检查。@elena:谢谢你的编辑。我又错改了一次,但现在又改成了你的version@elena:谢谢你的编辑。我又错改了一次,但现在又改成了你的版本