【发布时间】:2020-04-18 23:33:55
【问题描述】:
我需要构建一个从 Python 中的字符串中删除所有数字的函数,但是我的问题不在于如何做到这一点(因为我从这里以前的帖子中知道)
我对这两个函数的复杂性有疑问,一个是使用过滤器和 lambda 函数来删除数字,另一个是使用正则表达式,来自具有非常长字符串(~67,912,000 个字符 +)的基本测试
我得出的结论是正则表达式更快,但是我不知道实际的复杂性,因此我的“计算”不正确/对计算机规格有偏见(也许我的计算机速度很快,而其他的计算机速度很慢,反之亦然...... )
从互联网上阅读the filter function 和complexity of regex 的复杂性
我知道他们都是 O(n)..
那么,哪一个在内存/时间复杂度上“过大”,哪一个不是。您应该使用哪一个(作为一种更好的做法)?:
import time
import re
def dwf(word):
start = time.time()
word = ''.join((filter(lambda x: x.isalpha(), word)))
end = time.time()
return end - start
def dwr(word):
start = time.time()
word = re.sub(r"\d+", '', word)
end = time.time()
return end-start
例如,对我来说:
如果这个词是 6700 万~chars,时间差接近 7 秒! (当过滤器更长且正则表达式更快时)
【问题讨论】:
-
如果你关心速度,你应该编译你的正则表达式(一次)。
-
@TomKarzes 'compile (once)' 是什么意思,或者我没有完全得到你的答案,你基本上是说使用过滤器是一种矫枉过正,我应该使用正则表达式跨度>
-
@TomKarzes -
re保留最近正则表达式的缓存。只要不大量使用,就不需要预编译。 -
即使它们都具有相同的复杂性,它们仍然可能线性相差 100 倍。正则表达式是用 C 编写的,只在几个缓冲区上工作。在您的过滤器示例中,您需要为每个字符创建一个对象并调用该 lambda 函数。这里没有竞争!
-
Python 是一门很棒的语言,但它的对象模型相当庞大。当您执行
filter(..., word)时,word 中的每个字符都需要转换为具有单个字符(约 50 个字节)的str,需要为lambda等创建一个框架对象...... Python 的正则表达式引擎在 C 中实现,因此它可以处理内存中的原始字符。任何语言都可以在本地实现正则表达式,但是由于性能优势,基于 C 的语言(如 python(无论如何是 cpython))经常退回到 C 进行此操作。
标签: python regex filter time-complexity big-o