如何在包含在python中以空格分隔的单词组成的文件中找到与第一个字符串匹配的单词?

时间:2013-10-15 00:55:40

标签: python file search

让我更好地解释我的问题! 我有一个这种格式的输入文件

word1 word2  
word3 word4 word5  
word4 word6

鉴于word3,我希望能够得到整行并获得word4和word5。

打开文件,可以解析每一行,但我的文件很大,需要很长时间。 是否有成本效益的方式可以做到这一点?

任何帮助表示赞赏!

3 个答案:

答案 0 :(得分:1)

除非数据以某种可预测的方式排序(例如已排序),否则您读取每一行以找到相关的数据。

with open('/path/file.txt') as input:
    for line in input:
        words = line.split()
        if words and words[0] == 'trigger':
            print words[1:]
            break  # delete this line if you may have multiple matches

以上内容不会立即将整个文件读入内存(如果它很大) - 它会逐行处理这些行(它们将以缓冲区大小的块读取)。

如果所有线条的尺寸相同且非常长,那么可能会有一个改进。然后你可以读取每一行的开头。但是他们必须非常长才有用。

如果您使用的是unix,那么您可能会发现在子进程中执行grep命令会更快。但这仍然会扫描整个文件(虽然更快,在优化的c代码中)。

答案 1 :(得分:0)

Python的linecache模块是我从文件中查找给定行号的最快方式。你想要一行匹配该行中的第一个单词,但也许我们可以使用linecache来实现。那么让我们创建一个从单词到行号的映射:

from linecache import getline, getlines
from collections import defaultdict
first_words = defaultdict(int)
first_words.update(
  (line.split()[0], number)
  for number, line in enumerate(getlines(filename), 1)
  if line
)

从这里开始,只需这样做:

>>> getline(filename, first_words['word3'])
'word3 word4 word5\n'
>>> getline(filename, first_words['word4'])
'word4 word6\n'

如果你试图得到一个不是一行中第一个单词的单词,你就会得到一个空字符串。

>>> getline(filename, first_words['word6'])
''

现在,我想你可能会在某些行开头有相同的单词,在这种情况下你可能想要获得多行。所以这是一个修改版本,说明了这种情况:

from linecache import getline, getlines
from collections import defaultdict
from operator import itemgetter
first_words = defaultdict(list)
for number, line in enumerate(getlines(filename), 1):
  if line:
    first_words[line.split(0)].append(number)

现在获取行:

itemgetter(*first_words['word3'])(getlines(filename))

答案 2 :(得分:0)

我不认为使用readlines()确实是内存或时间问题。以下是我使用 4000 行的文件的简短示例,每行最少有 600 个字母。

import MyUtils as utils
LOGDIR = '/opt/lsf_events/7.0.6/work/blr_ifx/logdir/lsb.acct.1'

utils.Timer.start()
with open(LOGDIR,'r') as fHeader:
for line in fHeader.readlines():
    if '1381671028' in line: #that particular number exists in the last line of the file.
         print line
utils.Timer.end()  

输出是......

Started Recording Time for the process...
"JOB_FINISH" "7.06" 1381671036 51303 22965 503578626 1 1381671028 0 0 1381671028 "umashank" "batch" "select[ ((type==X64LIN && osrel==50 && clearcase))]" "" "" "blrlc275" "/home/padbgl/spt9_m5p120_5v0_cm112/nodm/default/units/top/simulation/titan/FE/TPL_100_tx_top_new_ls" "" "" "" "1381671028.51303" 0 1 "blrlc275" 64 225.0 "" "/home/padbgl/bin/prjgate -e -- /home/umashank/.lsbatch/blrlc275.21758.0.1381671027.TITAN" 1.037842 0.119981 10116 0 -1 0 0 21997 0 0 0 0 -1 0 0 0 3735 82 -1 "" "padbgl_spt9_m5p120_5v0_cm112" 0 1 "" "" 0 3068 44332 "" "" "" "" 0 "" 0 "" -1 "/umashank" "" "" "" -1 "" "" 5136 "" 1381671028 "" "" 0

Process ended at : 15-10-13 08:02:56 
Total time taken by the process is : 0:00:00.011601   

希望你可以舒服地使用readlines(),因为它花费的时间非常少,并且对于3mb的内存文件几乎是即时的。

这不是您要求的替代品,而只是试图告诉您如果您在阅读文件时使用典型的传统程序,不会有任何损害。