Каков наилучший способ использования регулярных выражений в цикле for при тестировании на тип данных? - PullRequest
0 голосов
/ 28 мая 2019

Каков наилучший способ использования регулярных выражений в цикле for при тестировании на тип данных?

Для контекста я перебираю большие нечистые наборы данных с несколькими типами данных, и мне нужно найти расширения строк, если они существуют. Небольшие изменения в моем коде, такие как преобразование значений в строку, стоят мне минут.

Я прочитал этот вопрос Python: Как использовать RegEx в операторе if? , но не смог найти способ проверки соответствия без предварительного преобразования в строку.

Значения:

vals = [444444, '555555-Z01']
pattern = re.compile('[-]*[A-Z]{1}[0-9]{2}$')
# new_vals = [444444, 555555]

Медленный метод: (2,4 мкс ± 93,6 нс на цикл)

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 мкс ± 34,7 нс на цикл)

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

1 Ответ

1 голос
/ 28 мая 2019

Я пытался побить ваши попытки, используя блоки try/except, но обработка исключений, кажется, занимает слишком много времени.Вот вам и «лучше попросить прощения, чем разрешения» ...

Ваша последняя попытка является наиболее многообещающей, если вы просто измените & на and, потому что & является логическим и не делаетt короткое замыкание.

Я пойду на это, в понимании списка, чтобы немного ускорить его, и отброшу тест 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)]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...