我已经有一个相当不错的代码片段,但是我想知道是否有更好的方法来实现这个功能:
val = ''.join([c for c in val if c in '1234567890.'])
你会怎么做?
我已经有一个相当不错的代码片段,但是我想知道是否有更好的方法来实现这个功能:
val = ''.join([c for c in val if c in '1234567890.'])
你会怎么做?
re
模块)来实现相同的功能。下面的示例匹配任何非十进制数字或句点字符的序列 [^\d.]
并将它们替换为空字符串。请注意,如果使用 UNICODE
标志编译该模式,则结果字符串仍可能包含 非 ASCII 数字。此外,移除“非数字”字符后的结果不一定是有效的数字。>>> import re
>>> non_decimal = re.compile(r'[^\d.]+')
>>> non_decimal.sub('', '12.34fe4e')
'12.344'
re.sub(r'[^\d.]+', '', '12.34fe4e')
即可。 - Ben Blank另一种“Pythonic”的方法
filter( lambda x: x in '0123456789.', s )
但正则表达式更快。
一个简单的解决方案是使用正则表达式。
import re
re.sub("[^0-9^.]", "", data)
以下是一些样例代码:
$ cat a.py
a = '27893jkasnf8u2qrtq2ntkjh8934yt8.298222rwagasjkijw'
for i in xrange(1000000):
''.join([c for c in a if c in '1234567890.'])
$ cat b.py
import re
non_decimal = re.compile(r'[^\d.]+')
a = '27893jkasnf8u2qrtq2ntkjh8934yt8.298222rwagasjkijw'
for i in xrange(1000000):
non_decimal.sub('', a)
$ cat c.py
a = '27893jkasnf8u2qrtq2ntkjh8934yt8.298222rwagasjkijw'
for i in xrange(1000000):
''.join([c for c in a if c.isdigit() or c == '.'])
$ cat d.py
a = '27893jkasnf8u2qrtq2ntkjh8934yt8.298222rwagasjkijw'
for i in xrange(1000000):
b = []
for c in a:
if c.isdigit() or c == '.': continue
b.append(c)
''.join(b)
并且这是时间测试结果:
$ time python a.py
real 0m24.735s
user 0m21.049s
sys 0m0.456s
$ time python b.py
real 0m10.775s
user 0m9.817s
sys 0m0.236s
$ time python c.py
real 0m38.255s
user 0m32.718s
sys 0m0.724s
$ time python d.py
real 0m46.040s
user 0m41.515s
sys 0m0.832s
目前看起来正则表达式是最好的选择。
就我个人而言,我认为正则表达式和列表推导式一样易读。如果你只需要使用它几次,那么编译正则表达式可能会花费更多时间。选择符合你的代码和编码风格的方式。
import string
filter(lambda c: c in string.digits + '.', s)
dec = set('1234567890.')
a = '27893jkasnf8u2qrtq2ntkjh8934yt8.298222rwagasjkijw'
for i in xrange(1000000):
''.join(ch for ch in a if ch in dec)
至少在我的系统上,如果你在a.py中使用生成器表达式而不是列表解析,可以节省一点时间(如果你的字符串足够长则可以节省内存):
a = '27893jkasnf8u2qrtq2ntkjh8934yt8.298222rwagasjkijw'
for i in xrange(1000000):
''.join(c for c in a if c in '1234567890.')
噢,这是我在这个测试字符串中找到的迄今为止最快的方法(比正则表达式快得多),如果你需要做很多次,并且愿意承受构建几个字符表的开销。
chrs = ''.join(chr(i) for i in xrange(256))
deletable = ''.join(ch for ch in chrs if ch not in '1234567890.')
a = '27893jkasnf8u2qrtq2ntkjh8934yt8.298222rwagasjkijw'
for i in xrange(1000000):
a.translate(chrs, deletable)
在我的系统上,该操作运行时间约为1.0秒,而正则表达式 b.py 运行时间约为4.3秒。