2015-01-31 187 views
1

我有以下问题。 我试图从字符串中删除所有非字母字符(即数字(string.digits),标点符号(string.punctuation),非ascii字符(如φ,χ,ψ等) 这可以是一个简单的命令一样轻松地完成。快速删除字符串中的所有非字母字符,python

for i in str: 
    if i not in string.ascii_letters: 
     data1 = str.replace(i,"") 

,或者使用过滤器 不过,我的问题是,我的字符串的长度大约为20.000.000(几本书串联在一起) 现在的情况。 3.000.000个字符,上面的命令花费了大约20分钟,因此我不敢用20,000.000个字符来尝试它。 能否请告诉我是否有真正快速的方法来做到这一点?

+0

你是否一次需要所有的角色?如果没有,你可以使用'itertools.ifilter'。另外,使用'set(string.ascii_letters)'意味着更高效的成员资格测试。 – jonrsharpe 2015-01-31 20:52:08

+2

你的代码甚至不会像你认为的那样工作。你正在运行'str.replace',它返回一个* new *字符串,将它赋值给'data1',然后在下一次找到另一个不在'in string.ascii_letters'中的字符时将结果扔掉。 – roippi 2015-01-31 20:54:58

回答

4

那样的东西可能最终提高性能,因为你没有你的很长的字符串的副本在RAM:

data1 = (c for c in my_string if c in string.ascii_letters) 

情况因人而异,但在我的系统,它需要像6s来过滤20MB的文件,其中包含随机的字节(含。需要"".join(...)操作要回一个字符串):

>>> data1 = (c for c in my_string if chr(ord(c)) in string.ascii_letters) 
>>> timeit.timeit('"".join(data1)', setup='from __main__ import data1') 
5.96341991424560 

正则表达式替换waaaayy花了更多的时间:

>>> timeit.timeit('re.sub("[^a-zA-Z]","",my_string)', setup='from __main__ import my_string; import re') 
... still running after 90+ minutes... 
2

我觉得正则表达式是为这种事做......

re.sub("[^a-zA-Z]","",my_string) 
相关问题