0

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()
3
  • 1
    Write a regular function using def instead. Commented Sep 9, 2016 at 2:11
  • @BrenBarn Yeah, I realized using def will be better when I had to move the cursor to read the function. Still, I'm interested in the answer. Commented Sep 9, 2016 at 2:19
  • 2
    The answer is write a regular function using def. There are things you can do in a def that you can't do in a lambda. There is nothing you can do in a lambda that you can't do in a def. If you can't do something with lambda and can do it with def, use def instead. Commented Sep 9, 2016 at 2:24

2 Answers 2

3

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
Sign up to request clarification or add additional context in comments.

Comments

1

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]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.