【问题标题】:What is the best way to use regex in a for loop while testing for data type?在测试数据类型时,在 for 循环中使用正则表达式的最佳方法是什么?
【发布时间】:2019-05-28 19:01:34
【问题描述】:

在测试数据类型时,在 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

【问题讨论】:

  • 啊:if ((type(v)==str) and (pattern.search(v) is not None)):& 不会短路
  • @Jean-FrançoisFabre 给出了答案。
  • 好吧,我会投票赞成错字。 OP不清楚结果。当已经有“快速”尝试时,第三次尝试的意义何在?我们应该保留非字符串值,还是将它们过滤掉?
  • 不要在比较中使用type(v)。请改用isinstance(v, str)
  • @chepner:当您确定对象是确切类型时,测试类型会更快

标签: python regex performance


【解决方案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)]

【讨论】:

  • 啊哈! if type(v)==str and pattern.search(v): 解决了!
  • 好。尝试我提到的列表理解方法。首先你会了解它们(这是值得的),其次我认为你会多节省几毫秒。
猜你喜欢
  • 2011-04-29
  • 2016-05-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-06
  • 2011-04-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多