Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/287.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_String_Performance_Algorithm_Data Structures - Fatal编程技术网

Python 有效替换单词列表中出现的单词

Python 有效替换单词列表中出现的单词,python,string,performance,algorithm,data-structures,Python,String,Performance,Algorithm,Data Structures,我需要检查所有出现的带有*的单词列表。我有大约400个单词在列表中,它将受到大量流量的影响,所以我想让它非常高效。什么是一种高效的算法/数据结构?最好是Python中已有的东西 示例: “滚开”=>“****滚开” “你好”=>“你好” “见鬼去吧”=>“见鬼去吧” 一个不区分大小写的支持集实现可能符合这个要求。对于每个单词,您将只处理最少的字符。例如,您只需要处理单词“zoo”的第一个字母,就知道该单词不在列表中(假设您没有“z”咒语) 然而,这并不是用python打包的。您可能会从简单的字典

我需要检查所有出现的带有*的单词列表。我有大约400个单词在列表中,它将受到大量流量的影响,所以我想让它非常高效。什么是一种高效的算法/数据结构?最好是Python中已有的东西

示例:

  • “滚开”=>“****滚开”
  • “你好”=>“你好”
  • “见鬼去吧”=>“见鬼去吧”
  • 一个不区分大小写的支持集实现可能符合这个要求。对于每个单词,您将只处理最少的字符。例如,您只需要处理单词“zoo”的第一个字母,就知道该单词不在列表中(假设您没有“z”咒语)


    然而,这并不是用python打包的。您可能会从简单的字典解决方案中看到更好的性能,因为它是用C实现的。

    如果性能是您想要的,我建议:

    • 获取输入的样本
    • 计算每行被删单词的平均数量
    • 定义每行要过滤的最大字数(例如3个)
    • 计算什么样的词在样本中点击率最高
    • 写一个函数,给定删失的单词,将生成一个 python文件中用IF语句检查每个单词,将 首先点击单词,因为你只想匹配整个单词 相当简单
    • 一旦达到每行的最大数量,退出该函数
    我知道这不好我之所以建议这种方法,是因为在高流量的情况下,循环列表中的每个单词会对性能产生巨大的负面影响

    希望这能对你有所帮助,或者至少能给你一些开箱即用的想法来解决这个问题。

    (1)让p成为需要审查的短语集

    (2) 预计算H={H(w)| p在p中,w是p}中的一个字,其中H是一个合理的哈希函数

    (3) 对于输入的每个单词v,测试h(v)是否在h中

    (4) 如果h(v)不在h中,则发射v

    (5) 如果h(v)在h中,返回到任何简单的方法,该方法将检查v和下面的单词是否构成p中的短语


    步骤(5)不是问题,因为我们假设p与输入量相比(非常)小。步骤(3)是一个O(1)操作。

    您可能需要对基于regexp的解决方案与其他解决方案进行计时。以前,我曾使用类似的基于regexp的文本替换,将一到三千个单词的短语转换为链接,但我不会为很多人提供这些页面

    我获取这组单词(可能是短语),并从中形成一个正则表达式,该表达式将匹配它们在文本中作为完整单词出现的情况,因为“\b”

    如果你有一本字典将单词映射到它们的净化版本,那么你可以使用它。为了方便起见,我把每个单数字母都换成了“*”

    sanitizer函数只返回任何匹配的脏话的净化版本,并在对文本的正则表达式替换调用中使用,以返回净化版本

    import re
    swearwords = set("Holy Cow".split())
    swear = re.compile(r'\b(%s)\b' % '|'.join(sorted(swearwords, key=lambda w: (-len(w), w))))
    sanitized = {sw:''.join((ch if not i % 2 else '*' for i,ch in enumerate(sw))) for sw in swearwords}
    
    def sanitizer(matchobj):
        return sanitized.get(matchobj.group(1), '????')
    
    txt = 'twat prick Holy Cow ... hell hello shitter bonk'
    swear.sub(sanitizer, txt)
    # Out[1]: 'twat prick H*l* C*w ... hell hello shitter bonk'
    
    您可能希望使用re.subn和count参数来限制所做的替换的数量,如果有太多的亵渎内容,只需拒绝整个文本:

    maxswear = 2
    newtxt, scount = swear.subn(sanitizer, txt, count=maxswear)
    if scount >= maxswear: newtxt = 'Ouch my ears hurt. Please tone it down' 
    print(newtxt)
    # 'Ouch my ears hurt. Please tone it down'
    

    正如cheeken所提到的,
    Trie
    可能是您需要的东西,实际上,您应该使用它。不只是一次尝试

    对于每个需要处理的字符串,比如说
    S
    ,时间复杂度大约为
    O(len(S))
    。我是说,线性的


    首先,你需要构建自动机,它的时间复杂度是
    O(sigma(len(words))
    ,空间复杂度是
    O(52*sigma(len(words))
    ,这里52表示字母表的大小(我认为它是
    ['a''z',a''z']
    )。你只需要这样做一次(或每次系统启动时)。

    你考虑过使用正则表达式吗?你的例子#2没有改变审查:不是旧的ChestNut审查输入上的单词,也不是当你想显示它们时。所以你不必担心traffic@phs正则表达式的效率不够。这是为了表明我特别想要匹配整个单词。我仍然需要处理其他字母以找到下一个单词的开头。不过,这可能确实有效。起初我对它不感兴趣,但现在我意识到,单词边界的匹配使它非常有效。没错,但没有办法避免至少琐碎地检查每个字符:至少,你必须找到每个空格(识别边界)。还请记住,您处理的这些额外字符仅用于查看它们是否为空格(您不必进行相对昂贵的树查找)。