2016-09-09 1 views
0

Я использую функцию лямбда извлечь число в строке:Избегайте дублирования операций в функции лямбда

text = "some text with a number: 31" 
get_number = lambda info,pattern: re.search('{}\s*(\d)'.format(pattern),info.lower()).group(1) if re.search('{}\s*(\d)'.format(pattern),info.lower()) else None 
get_number(text,'number:') 

Как я могу избежать, чтобы сделать эту операцию два раза ?:

re.search('{}\s*(\d)'.format(pattern),info.lower() 
+1

Вместо этого напишите регулярную функцию, используя 'def'. – BrenBarn

+0

@BrenBarn Да, я понял, что использование def будет лучше, когда мне нужно было переместить курсор, чтобы прочитать функцию. Тем не менее, меня интересует ответ. –

+2

Ответ - это регулярная функция, использующая 'def'. Есть вещи, которые вы можете сделать в 'def', которые вы не можете сделать в' lambda'. Вы ничего не можете сделать в «лямбде», которую вы не можете сделать в 'def'. Если вы не можете что-то сделать с 'lambda' и можете сделать это с помощью' def', вместо этого используйте 'def'. – BrenBarn

ответ

3

You может использовать findall() вместо этого, он обрабатывает нет соответствия изящно. or - единственное утверждение, необходимое для удовлетворения условий возврата. None оценивается последним, поэтому возвращается, если найден пустой список (неявная правдивость литералов, таких как списки).

>>> get_number = lambda info,pattern: re.findall('{}\s*(\d)'.format(pattern),info.lower()) or None 
>>> print get_number(text, 'number:') 
['3'] 
>>> print get_number(text, 'Hello World!') 
>>> 

Это, как говорится, я бы рекомендовал определение обычной функции имени используя def вместо этого. Вы можете извлечь более сложные части этого кода в переменные, что приведет к более простому алгоритму. Написание длинной анонимной функции может привести к запахам кода. Нечто подобное ниже:

def get_number(source_text, pattern): 
    regex = '{}\s*(\d)'.format(pattern) 
    matches = re.findall(regex, source_text.lower()) 
    return matches or None 
1

Это супер некрасиво, не буду врать, но он работает и избегает возвращения объекта матча, если он найден, но делает возвращения нет, если это не так:

lambda info,pattern: max(re.findall('{}\s*(\d)'.format(pattern),info.lower()),[None],key=lambda x: x != [])[0] 
Смежные вопросы