【问题标题】:Fastest way to check does string contain any word from list检查字符串是否包含列表中的任何单词的最快方法
【发布时间】:2015-03-03 02:34:48
【问题描述】:

我有 Python 应用程序。

有 450 个禁止短语的列表。有来自用户的消息。我想检查一下,这条消息是否包含任何禁止的短语。最快的方法是什么?

目前我有这个代码:

message = "sometext"
lista = ["a","b","c"]

isContaining = false

for a, member in enumerate(lista):
 if message.contains(lista[a]):
  isContaining = true
  break

有没有更快的方法来做到这一点?我需要在 1 秒内处理消息(最多 500 个字符)。

【问题讨论】:

  • isContaining = any(x in message for x in lista)
  • 首先,去掉enumeratea,部分。将lista[a] 替换为member。第二,in函数不是更快吗?所以像if member in message:
  • a set 上的会员测试更快。
  • 我认为你最好编译一个正则表达式并测试它上面的文本
  • 1秒很长,真的需要更长的时间吗?

标签: python string list contain


【解决方案1】:

有专门为此而设的any 内置函数:

>>> message = "sometext"
>>> lista = ["a","b","c"]
>>> any(a in message for a in lista)
False
>>> lista = ["a","b","e"]
>>> any(a in message for a in lista)
True

或者你可以检查集合的交集:

>>> lista = ["a","b","c"]
>>> set(message) & set(lista)
set([])
>>> lista = ["a","b","e"]
>>> set(message) & set(lista)
set(['e'])
>>> set(['test','sentence'])&set(['this','is','my','sentence'])
set(['sentence'])

但您将无法检查子词:

>>> set(['test','sentence'])&set(['this is my sentence'])

【讨论】:

  • 另外,对 lista 中的单词进行排序,使最小的在前(我假设这些单词在消息中出现的可能性最高)
  • set(message) 如果他要查找的是单词而不是字符,那么他将无法正常工作。
【解决方案2】:

我会将any 内置函数与in 运算符结合起来:

isContaining = any(a in message for a in lista)

我不知道这是否是最快的方法,但对我来说似乎是最简单的。

【讨论】:

    【解决方案3】:

    使用regex compile from list

    考虑内存和构建时间或表达式,提前编译。

    lista = [...]
    lista_escaped = [re.escape(item) for item in lista]
    bad_match = re.compile('|'.join(lista_escaped))
    is_bad = bad_match.search(message, re.IGNORECASE)
    

    【讨论】:

    • 结合 re.escape() 进行固定字符串搜索。 re.compile 将为扫描字符串创建一个经过优化的状态机。
    【解决方案4】:

    我们也可以使用setintersection方法

    >>> message = "sometext"
    >>> lista = ["a","b","c"]
    >>> isContaining = False
    >>> if set(list(message)).intersection(set(lista)):
    ...    isContaining = True
    ... 
    >>> isContaining
    False
    >>> message = "sometext a"
    >>> list(message)
    ['s', 'o', 'm', 'e', 't', 'e', 'x', 't', ' ', 'a']
    >>> if set(list(message)).intersection(set(lista)):
    ...    isContaining = True
    ... 
    >>> isContaining
    True
    

    【讨论】:

    • 是的,我需要创建message 字符串的所有组合的列表。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-12
    相关资源
    最近更新 更多