使用插值搜索在大文本文件中查找列表的开头 - Python

时间:2018-01-22 20:45:38

标签: python search interpolation large-files

在到达带有时间戳的行之前,我需要在一个包含未知行数的非常大的日志文件中找到最后一个时间戳。我一次向后读一行文件,除了一个案例,通常很快。有时,我会遇到一个非常大的块(数千行),它具有已知的重复模式(下面显示的一个条目)并且没有时间戳:

  goal_tolerance[0]: 
    name: joint_b
    position: -1
    velocity: -1
    acceleration: -1

由于这是我遇到这种问题的唯一情况,我可以将一段代码抛入循环中,在逐行搜索日志之前检查它。

goal_tolerance之后的数字是一个计数器,每次模式重复时增加1,所以我想要用的是用这个数字计算模式的开头。我现在看起来像这样:

if '  goal_tolerance' in line:
    gtolnum = line[17:-3]
    print gtolnum
    startFrom = currentPosition - ((long(gtolnum) + 1) * 95)
    break

但是,这并没有考虑到计数器中的字符数,所以我最终在搜索循环中运行的次数超过了必要的次数。有没有快速的方法在计算中包含这些字符?

编辑:我没有阅读整个文件到达那一点,因为它很大,我有几百个时间戳在几百个日志文件中搜索。我的搜索功能寻找文本文件中的位置,然后找到该点附近的行的开头并读取它。计算是根据模式中的字节数或字符数确定可以与.seek()一起使用的文件位置。

1 个答案:

答案 0 :(得分:0)

我在此期间做了一些数学计算并得出了一个数学解决方案:

...
n = long(gtolnum)
q = len(gtolnum)        # I'll refer to this as the number's "level"
x = n + 1 - 10**(q - 1) # Number of entries in the current level
c = x * (q - 1)         # Additional digits in the current level
i = 2
p = 0
while i < q:
    p += 9 * (q - i) * (10**(q - i))  # Additional digits in i levels previous
    i += 1
startFrom = currentPosition - ((n + 1) * 95 + p + c)
...

似乎应该有一个更简单的解决方案,但我没有看到它。也许日志功能可以帮助吗?