0

我有一个看起来像这样的输入文件:

#nP 4
#mP 0.0262
#mH     10
#HP various info:
14  H   0.026
19  P   0.054
20  H   0.012
512 H   0.005
#xP
#kP
99
89
90

我想从第 5 行开始提取 4 行(因为第一行中的 np = 4),所以输出将是这样的:

14  H   0.026
19  P   0.054
20  H   0.012
512 H   0.005

我试过这个:

import sys

head = sys.stdin.readline()
head = head.strip()
head = head.split('\t')
cntHetPos = int(head[1])
if "#HP" in sys.stdin.readlines():
  lines = sys.stdin.readlines()[0:cntHetPos]
  print lines

但它不会打印出这些行,也不会给出错误消息。我基于之前在这里找到的答案:从第 2 行读取文件或跳过标题行 想法?

4

4 回答 4

2

readlines()第一次调用它时返回所有行的列表,但第二次它是空的,因为所有行都已被读取和使用。将它们存储在一个变量中:

lines = sys.stdin.readlines()

将其放在顶部,因为您不妨使用它head从以下位置读取变量:

head = lines[0]

另一个问题是您需要遍历所有行以查找#HP令牌,并且您需要跟踪行号以便正确分割列表:

for i, line in enumerate(lines):
  if "#HP" in line:
    lines = lines[i+1 : i+1+cntHetPos]

最后,如果要打印行而不是格式化列表,则需要加入它们(注意行尾字符已经在其中):

    print ''.join(lines),

而且,为了更好的衡量,我们可以在找到正确的线路break后立即停止,所以我们会在print.

总结一下:

import sys

lines = sys.stdin.readlines()
head = lines[0]
head = head.strip()
head = head.split('\t')
cntHetPos = int(head[1])
for i, line in enumerate(lines):
  if "#HP" in line:
    lines = lines[i+1 : i+1+cntHetPos]
    print ''.join(lines),
    break
于 2013-04-08T11:03:57.360 回答
0

这是一个非常难看的匹配模式,但它可能符合您的需求;

/#nP.*?#HP.*?$.*?(\d+ +\w +[\d\.]+).*?(\d+ +\w +[\d\.]+).*?(\d+ +\w +[\d\.]+).*?(\d+ +\w +[\d\.]+)/gsm

它会将您想要抓取的 4 行的结果分组并将它们分组。您甚至可以对结果进行分组,以便立即获得14 H 0.026单独的结果。就像是;

(\d+) +(\w) +([\d\.]+)

例子

import re

string = '''#nP 4
#mP 0.0262
#mH     10
#HP various info:
14  H   0.026
19  P   0.054
20  H   0.012
512 H   0.005'''

result = re.findall('#nP.*?#HP.*?$.*?(\d+ +\w +[\d\.]+).*?(\d+ +\w +[\d\.]+).*?(\d+ +\w +[\d\.]+).*?(\d+ +\w +[\d\.]+)', string, re.S | re.M)

print(result)

输出

[('14  H   0.026', '19  P   0.054', '20  H   0.012', '512 H   0.005')]
于 2013-04-08T11:02:39.600 回答
0

也许是这样的:

from itertools import islice

with open('yourfile') as fin:
    count = int(next(fin).split()[1])
    non_comments = (line for line in fin if not line.startswith('#'))
    print list(islice(non_comments, None, count))
    # ['14  H   0.026\n', '19  P   0.054\n', '20  H   0.012\n', '512 H   0.005\n']
于 2013-04-08T11:24:36.877 回答
0

linecache 模块专为高效地从文件中读取行而设计:

linecache 模块允许从任何文件中获取任何行,同时尝试使用缓存进行内部优化,这是从单个文件中读取多行的常见情况。回溯模块使用它来检索源代码行以包含在格式化的回溯中。

假设调用了文本文件blah,并且文件数据从第五行开始:

#!/usr/bin/python   

import linecache

starting_line_number = 5   
number_of_lines      = int(linecache.getline('blah',1).split()[1])
for line_num in range(starting_line_number, starting_line_number+number_of_lines):
    print linecache.getline('blah',line_num),
于 2013-04-08T11:33:03.613 回答