Reputation: 10373
I'm using a lambda function to extract the number in a string:
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:')
How can I avoid to make this operation twice?:
re.search('{}\s*(\d)'.format(pattern),info.lower()
Upvotes: 0
Views: 54
Reputation: 3525
You can use findall()
instead, it handles a no match gracefully. or
is the only statement needed to satisfy the return conditions. The None
is evaluated last, thus returned if an empty list is found (implicit truthiness of literals like lists).
>>> 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!')
>>>
That being said, I'd recommend defining a regular named function using def
instead. You can extract more complex parts of this code to variables, leading to an easier to follow algorithm. Writing long anonymous function can lead to code smells. Something similar to below:
def get_number(source_text, pattern):
regex = '{}\s*(\d)'.format(pattern)
matches = re.findall(regex, source_text.lower())
return matches or None
Upvotes: 3
Reputation: 4548
This is super ugly, not going to lie, but it does work and avoids returning a match object if it's found, but does return None when it's not:
lambda info,pattern: max(re.findall('{}\s*(\d)'.format(pattern),info.lower()),[None],key=lambda x: x != [])[0]
Upvotes: 1