在测试数据类型时,在for循环中使用正则表达式的最佳方法是什么?
对于上下文,我正在遍历具有多种数据类型的大型不干净数据集,并且需要查找字符串扩展名(如果存在)。对我的代码进行少量更改(例如将值转换为字符串)会花费我几分钟的时间。
我通读了这个问题Python: How to use RegEx in an if statement?,但没有找到一种方法来测试是否匹配,而没有先转换为字符串。
值:
vals = [444444, '555555-Z01']
pattern = re.compile('[-]*[A-Z]{1}[0-9]{2}$')
# new_vals = [444444, 555555]
慢速方法: (每个循环2.4 µs±93.6 ns)
new_vals = []
for v in vals:
if type(v)==str:
if pattern.search(v) is not None:
new_v = pattern.findall(v)[0].replace('-','')
new_vals.append(new_v)
else:
new_vals.append(v)
快速方法: (每个循环1.84 µs±34.7 ns)
f = lambda x: x if type(x)!=str else pattern.findall(x)[0].replace('-','')
new_vals = []
for v in vals:
new_vals.append(f(v))
方法失败:
new_vals = []
for v in vals:
if ((type(v)==str) & (pattern.search(v) is not None)):
new_vals.append(v)
错误:
TypeError: expected string or bytes-like object
答案 0 :(得分:1)
我尝试使用try/except
块来击败您的尝试,但是异常处理似乎花费了太多时间。 “要宽恕多于允许”要这么多……
如果仅将&
换成and
,则最后一次尝试是最有前途的,因为&
是合乎逻辑的并且不会短路。
为此,我将在列表理解中加快速度,并放弃is not None
测试,这是无用的,因为如果search
成功,它将返回一个正则表达式对象,即诚实:
new_vals = [v for v in vals if type(v)==str and pattern.search(v)]
或使用isinstance
(同样的速度,也测试str
的子类):
new_vals = [v for v in vals if isinstance(v,str) and pattern.search(v)]