Python:优化过滤器字符方法的运行时所需的建议

时间:2014-11-07 18:30:58

标签: python optimization

我目前有一个需要优化的方法! 我还在学习python,所以非常感谢帮助!

我正在尝试针对非常大的语料库运行下面的方法,我需要优化/缩短此方法的运行时间,因为它已经占用大约6秒钟。

要求:

  1. 检查单词只包含字母,连字符和撇号
  2. 单词的第一个字符必须是字母
  3. 单词的最后一个字符必须是字母或撇号。
  4. 严格禁止使用re库(正则表达式)
  5. 以下是代码:

    def delUnknownChar(w):
        wf = []
        for c in w:
            if (c == "'" or c == "-" or c.isalpha()):
                wf.append(c)
    
        w = "".join(wf)
        wf.clear()
    
        if (len(w) > 1):
            while(not w[0].isalpha()):
                w = w[1:]
    
            while (w[-1] == "-"):
                w = w[:-1]
    
            return w
        else:
            return None
    
    string1 = delUnknownChar("-'test'-")
    print(string1)
    

    输出测试' 上面的代码大约需要5秒钟才能运行。

    如果我将代码的第2-7行更改为此行:

    w = "".join(c for c in w if c == "'" or c == "-" or c.isalpha())
    

    运行时以某种方式再增加1秒。

    这里有没有人有更好的想法或改进的优化方式以更快的速度检查这个?谢谢!

3 个答案:

答案 0 :(得分:1)

使用

之一
def Filter(In):
    # First alpha character
    for b in range(len(In)):
        if In[b].isalpha():
            break
    if b == len(In):
        return ""

    # Last alpha' character
    for e in range(len(In), 0, -1):
        if In[e - 1].isalpha() or In[e - 1] == "'":
            break

    # Middle alpha-' characters
    Out= [In[b]]  
    for i in range(b + 1, e):
      if In[i].isalpha() or In[i] == "-" or In[i] == "'":
        Out+= In[i]   

    return "".join(Out)

def Filter(In):
    # First alpha character
    for b in range(len(In)):
        if In[b].isalpha():
            break
    if b == len(In):
        return ""

    # Last alpha' character
    for e in range(len(In), 0, -1):
        if In[e - 1].isalpha() or In[e - 1] == "'":
            break

    # Middle alpha-' characters
    Out= In[b]
    for i in range(b + 1, e):
      if In[i].isalpha() or In[i] == "-" or In[i] == "'":
        Out+= In[i] 

    return Out

根据您的字符串分布和Python版本/平台,使用最快的。

更新:这是一个基于更好地理解规格的新版本。

答案 1 :(得分:-1)

尝试str.translate

from string import punctuation,digits

def delUnknownChar(s):
    trans = """!"#$%&()*+,./:;<=>?@[\]^_`{|}~0123456789"""
    return s.translate(None,trans).lstrip("-'").rstrip("-")

Python 3:

trans = """!"#$%&()*+,./:;<=>?@[\]^_`{|}~0123456789"""
d = {k: "" for k in trans}
def delUnknownChar1(s):
    return s.translate(str.maketrans(d)).lstrip("-'").rstrip("-")

没有翻译:

def delUnknownChar1(s):
    good = set("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-'")
    clean = ""
    for ele in s:
        if ele in good:
            clean += ele
    return clean.lstrip("-'").rstrip("-")

static str.maketrans(x [,y [,z]])

此静态方法返回可用于str.translate()的转换表。 如果只有一个参数,则它必须是将Unicode序数(整数)或字符(长度为1的字符串)映射到Unicode序数,字符串(任意长度)或无的字典。然后将字符键转换为序数。 如果有两个参数,则它们必须是长度相等的字符串,并且在结果字典中,x中的每个字符将映射到y中相同位置的字符。如果有第三个参数,则它必须是一个字符串,其结果中的字符将映射到None。

In [30]: timeit Filter(s)
100 loops, best of 3: 10.48 ms per loop

In [31]: timeit delUnknownChar(s) # yours
100 loops, best of 3: 8.41 ms per loop

In [32]: timeit delUnknownChar1(s) # mine
100 loops, best of 3: 2.46 ms per loop
In [25]: timeit delUnknownChar1(s)
100 loops, best of 3: 3.72 ms per loop

答案 2 :(得分:-1)

使用一些标准库:

import string

filter_set = set(string.ascii_letters + "-'")

def delUnknownChar(w):
    return ''.join(c for c in w if c in filter_set).lstrip("'-").rstrip("-")

使用translate的替代方法:

import string

keep = string.ascii_letters + "-'"
allchars = string.maketrans('', '')
delchars = ''.join([c for c in allchars if c not in keep])

def delUnknownChar(w):
    return w.translate(None, delchars).lstrip("'-").rstrip("-")

(基于this solution