我试图在一个非常大的语料库上运行下面的方法,并且我需要优化/减少这个方法的运行时间,因为它已经占用了大约6秒的时间来执行。
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秒。
有没有人有一个更好的想法或改进的优化方法来检查这一速度快得多?
发布于 2014-11-07 22:11:12
w = w[:-1]
可能效率低下,因为它要求对列表中的每个元素执行一个副本,减去一个。del w[-1]
是删除列表最后一个元素的惯用方法。isalpha
对应的字符串中的字符可能比完全等于"'"
或"-"
的字符多。因此,在其他两个条件之前检查isalpha
,您可能会注意到速度的提高。isalpha
、"'"
和"*"
的所有值的表,然后检查该表中是否有一个字符。但是,我不认为它能给您带来显著的速度改进,除非您使用可能被优化的专用str
方法(例如,replace
)进行过滤。一些关于风格的注释:
while
条件下插入括号,这与Python指南(PEP8)背道而驰。if
也是如此。发布于 2014-11-07 22:56:04
w(不是w0.isalpha()):W= w1:
当执行到达这段代码时,所有非字母或-'
的字符都已被删除。因此,与其检查not .isalpha
,不如检查字符是-
还是'
,这样会更有效:
while w[0] == "'" or w[0] == '-':
w = w[1:]
方法的名称不是很大。delUnknownChar
听起来像是“删除未知字符”,但这并不能很好地描述该方法的功能。您的要求比仅仅删除字符要复杂得多。比如sanitize_text
,或者normalize_input
会更好。
变量名w
和wf
不是很好:
letters
而不是wf
会更好word
而不是w
会更好有一个要求,你忘了包括在你的描述:字必须长于一个字符。
应该将需求添加为方法的docstring。
发布于 2014-11-07 22:28:51
所有这些在很大程度上取决于您的输入,因此假设您有完整的Unicode输入,因此不能使用str.translate
或任何其他基于C的函数,这可能要快得多(或者用另一种实现/语言重写),我首先要重写到:
def delUnknownChar(w):
w = [c for c in w if c == "'" or c == "-" or c.isalpha()]
if len(w) == 0:
return None
for i in range(len(w)):
if w[i].isalpha():
w = w[i:]
break
for i in range(len(w)-1, -1, -1):
if w[i] != "-":
w = w[:i+1]
break
return "".join(w)
因此,首先查找有效范围,然后执行下标一次,并且只进行一次到字符串的转换。恐怕不算太快。
另一种尝试是做同样的事,但更根本地避免不必要的转换:
def deleteUnknownCharacters(word):
l = len(word)
start = None
for i in range(l):
if word[i].isalpha():
start = i
break
if start == None:
return None
end = None
for i in range(l-1, -1, -1):
c = word[i]
if c == "'" or c.isalpha():
end = i
break
elif i <= start:
break
if start == None:
return None
result = [c for c in word[start:end+1] if c == "'" or c == "-" or c.isalpha()]
if len(result) == 0:
return None
return "".join(result)
这可能会更快,取决于您的输入,否则在某种程度上与我所能知道的是相等的。
https://codereview.stackexchange.com/questions/69184
复制相似问题