使用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:谢谢你的编辑。我又错改了一次,但现在又改成了你的版本