【问题标题】:What is a good data structure to use for a very long list of strings? [duplicate]对于很长的字符串列表,什么是好的数据结构? [复制]
【发布时间】:2017-09-24 04:40:10
【问题描述】:

我有一个非常大的文件 (80 GB),每行包含一个句子。我想在此文件中搜索用户给定的字符串以匹配匹配项(空格、连字符、要忽略的大小写)。

现在我将文件作为文本保存,并且我正在使用 grep,但这需要很多时间。有什么更好的解决方案?

文本文件内容示例:

 applachian
 rocky mountains
 andes
 sierra nevada
 long mountain ranges of the world

搜索查询示例:

rocky (no match)
sierra nevada (match found)

【问题讨论】:

  • 您在寻找什么?是“单词”,还是“字母”或“短语”?
  • 你关心文件中句子的顺序吗?
  • 下一个:你会这样做吗?循环上百次?响应网络请求?
  • 快速思考:您可以将文本分成几个块并运行尽可能多的线程,以便它们可以同时搜索。
  • 一般来说,setdict 数据结构对于像您建议的那样的成员资格测试最有效。

标签: python python-2.7 search text


【解决方案1】:

您可以通过将句子映射到哈希来构建可分片数据库,然后您可以在潜在位置查找数据。

from collections import defaultdict
from cStringIO import StringIO

DATA = """applachian
rocky mountains
andes
sierra nevada
long mountain ranges of the world"""


def normalize(sentence):
    return "".join(sentence.lower().strip())


def create_db(inf):
    db = defaultdict(list)
    offset = 0
    for line in inf:
        l = len(line)
        db[hash(normalize(line))].append((offset, l))
        offset += l
    return db


def main():
    db = create_db(StringIO(DATA))
    # save this db, and in a different script, load it to retrieve:
    for needle in ["rocky", "sierra nevada"]:
        key = hash(normalize(needle))
        for offset, length in db.get(key, []):
            print "possibly found at", offset, length


if __name__ == '__main__':
    main()

这展示了这个想法:您构建了一个数据库(例如存储为 pickle),其中包含所有标准化搜索键映射到找到这些键的位置。然后您可以快速检索偏移量和长度,并在实际文件中查找该位置,进行适当的基于 == 的比较。

【讨论】:

    【解决方案2】:

    根据您正在搜索整个句子的评论:

    建立前缀索引。

    对文件进行排序。接下来,处理您的文件一次。计算将搜索减少到 1000 个句子所需的前缀长度。也就是说,在给定句子的大约 1000 个句子中,您需要获得多少个前缀字符。

    例如:“The”可能是英语中常见的起始词。但是“The quick”可能已经足够接近了,因为“q”是低频的,类似于“The quick brown fox ...等”。

    这样做的一种方法是将所有前缀达到一定长度(例如,40)放入 Collections.counter。找到每个长度的最大计数,然后选择你的长度,使最大值

    现在,再次处理文件。建立一个单独的索引文件,由前缀长度(在文件头中)、前缀和偏移量组成。所有以前缀 K 开头的句子都从偏移量 V 开始。由于文件已排序,因此索引也将被排序。

    您的程序可以将索引读入内存、打开文件并开始处理搜索。对于每次搜索,去掉前缀,在索引中查找,寻找文件偏移量,然后扫描匹配。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-03
      • 1970-01-01
      • 2021-06-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多