Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/294.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在由python中空格分隔的单词组成的文件中找到与第一个字符串匹配的单词?_Python_File_Search - Fatal编程技术网

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

如何在由python中空格分隔的单词组成的文件中找到与第一个字符串匹配的单词?,python,file,search,Python,File,Search,让我更好地解释我的问题! 我有一个这种格式的输入文件 word1 word2 word3 word4 word5 word4 word6 给定word3,我希望能够获得整行并获得word4和word5 打开文件,可以对每一行进行解析,但是我的文件很大,而且需要很长时间。 是否有一种成本效益高的方法可以做到这一点 感谢您的帮助 除非数据以某种可预测的方式排序(如排序),否则您必须阅读每一行以找到相关的一行 with open('/path/file.txt') as input:

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

word1 word2  
word3 word4 word5  
word4 word6
给定word3,我希望能够获得整行并获得word4和word5

打开文件,可以对每一行进行解析,但是我的文件很大,而且需要很长时间。 是否有一种成本效益高的方法可以做到这一点


感谢您的帮助

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

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
comand会更快。但这仍然会扫描整个文件(尽管在优化的c代码中速度更快)

Python模块是我所知道的从文件中查找给定行号的最快方法。您需要一行匹配该行中的第一个单词,但也许我们可以使用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))

我不认为使用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的文件来说几乎是即时的


这不是您要求的替代方案,只是想告诉您,如果您使用典型的传统程序读取文件,不会造成任何损坏。

快速问题:您是说打开一次文件需要太长时间,在内存中创建包含所有信息的数据结构,关闭文件,然后查询数据结构?或者您是说每次查询word3时打开文件会花费太长时间?文件大小很大,因此执行readlines()获取一行,然后为文件中的每一行匹配字符串将花费很长时间。由于内存限制,我不希望解析整个文件并将其置于数据结构中。在我的情况下,打开文件不会花费太多时间。。