5

感谢您惊人的快速响应。Stackoverflow 太棒了!

我需要检查一个单词(或者说是数千个)是否与包含关键字的 dict 匹配。

例如,假设我有一个字符串:"The fluffy fox jumped the friggin fence." 我需要根据关键字字典检查字符串的每个单词,如果匹配,则返回所有值。

我创建了一个 dict filters:(uniqueid意思是“lk2m3lk4m2”,其余的是“静态”。)

filters:
        { "fox" : [
                    { 'subscription' : 'uniqueid', 'link' : 'uniqueid' },
                    { 'subscription' : 'uniqueid', 'link' : 'uniqueid' }
                  ]},

        { "fence" : [
                      { 'subscription' : 'uniqueid', 'link' : 'uniqueid' }
                    ]}

...并计划为字符串中的每个单词迭代过滤器(我必须以每秒 5000 个单词的速度执行此操作。换句话说,性能是最重要的问题。

过滤关键字的数量可能会增长到数千,而字符串的长度永远不会超过一个正常的句子(即 5-20 个单词)。因此,我将遍历字符串中的每个单词并检查它是否包含在过滤器列表中。但是,以 500 句/秒的速度,我仍在查看大量计算。

例如,是否可以对列表进行排序(即列表中 dict 的键),从而显着提高性能?是否有我应该使用的 C 实现(比如我正在使用 cjson 并获得很大的性能提升)?

抱歉,这个问题有点不稳定——但我应该如何完成这项任务?

编辑:

预期输入:
"The fluffy fox jumped the friggin fence."
预期输出:(
{ 'subscription' : 'flskdmfslk32232', 'link' : 'sfdksmfls22323' }, { 'subscription' : '3023940fsdf', 'link' : 'sdflsfm223' }
即每个匹配关键字下列出的订阅。)

4

2 回答 2

4

您可以通过执行 filters.has_key(word) 或执行以下操作来确定一个单词是否是过滤器中的键:

subscriptions = filters.get(word)
if subscriptions is not None:
    pass # TODO do something with subscriptions

或者:

try:
    subscriptions = filters[word]
    # TODO do something with subscriptions
except:
    pass # probably don't need to do anything if not present

没有必要遍历过滤器中的每个条目。相反,您将希望拆分输入字符串,将每个单词添加到 Set(以消除重复项),然后遍历您的集合以查找过滤器字典中的每个单词。

于 2012-11-12T20:46:40.567 回答
2

在 Python 中最快的方法是使用字典查找句子中的每个单词,并累积和关联值。主要的数据结构可能看起来像这样:

filters = {
    "fox" : (
              ('uniqueid1', 'uniqueid2'),
              ('uniqueid3', 'uniqueid4'),
            ),
    "fence" : (
                ('uniqueid5', 'uniqueid6'),
              ),
          }

使用这种方式(在 8 位字符上):

from string import punctuation

sentence = 'The fluffy fox jumped the friggin fence.'
sentence = sentence.translate(None, punctuation)  # remove punctuation chars

print [filters.get(word) for word in sentence.split() if word in filters]

或者它可能会更快(找出时间),这样可以避免双重字典查找:

from string import punctuation

def map_words(sentence):
    for word in sentence.translate(None, punctuation).split():
        try:
            yield filters[word]
        except KeyError:
            pass

sentence = 'The fluffy fox jumped the friggin fence.'
print [v for v in map_words(sentence)]

无论哪种方式,这都是输出:

[(('uniqueid1', 'uniqueid2'), ('uniqueid3', 'uniqueid4')), (('uniqueid5', 'uniqueid6'),)]
于 2012-11-12T20:44:00.090 回答