我不会为此使用 RegEx。速度慢了很多!
我们只使用一个简单的for 循环。
TLDR;
此功能将快速完成工作...
def filter_non_digits(string: str) -> str:
result = ''
for char in string:
if char in '1234567890':
result += char
return result
解释
让我们创建一个非常基本的基准来测试已提出的几种不同方法。我将测试三种方法...
- For 循环方法(我的想法)。
- 来自Jon Clements' answer的列表理解方法。
- 来自Moradnejad's answer 的RegEx 方法。
# filters.py
import re
# For loop method
def filter_non_digits_for(string: str) -> str:
result = ''
for char in string:
if char in '1234567890':
result += char
return result
# Comprehension method
def filter_non_digits_comp(s: str) -> str:
return ''.join(ch for ch in s if ch.isdigit())
# RegEx method
def filter_non_digits_re(string: str) -> str:
return re.sub('[^\d]','', string)
现在我们已经实现了每种删除数字的方法,让我们对每一种方法进行基准测试。
这里是一些非常基本和基本的基准代码。但是,它会起到作用,并让我们很好地比较每种方法的执行情况。
# tests.py
import time, platform
from filters import filter_non_digits_re,
filter_non_digits_comp,
filter_non_digits_for
def benchmark_func(func):
start = time.time()
# the "_" in the number just makes it more readable
for i in range(100_000):
func('afes098u98sfe')
end = time.time()
return (end-start)/100_000
def bench_all():
print(f'# System ({platform.system()} {platform.machine()})')
print(f'# Python {platform.python_version()}\n')
tests = [
filter_non_digits_re,
filter_non_digits_comp,
filter_non_digits_for,
]
for t in tests:
duration = benchmark_func(t)
ns = round(duration * 1_000_000_000)
print(f'{t.__name__.ljust(30)} {str(ns).rjust(6)} ns/op')
if __name__ == "__main__":
bench_all()
这是基准代码的输出。
# System (Windows AMD64)
# Python 3.9.8
filter_non_digits_re 2920 ns/op
filter_non_digits_comp 1280 ns/op
filter_non_digits_for 660 ns/op
如您所见,filter_non_digits_for() 函数比使用 RegEx 快四倍以上,大约是理解方法的两倍。有时简单是最好的。