How can one use Lambda expression to concatenate all numbers from 1-9 together before operand?
if I have a string like
Str = "21 2 4 + 21 1"
and want it formatet to:
newStr = "2124"
Why not with a regular expression?
import re
s = "21 2 4 + 21 1"
new_s = re.match(r'([\d ]+)[-+/*]', s).group(1).replace(' ', '')
Or with string methods?
s = "21 2 4 + 21 1"
new_s = s.split('+')[0].replace(' ', '')
re.match returns an object with a group method, which returns a string. For the string method version, a simple for opr in '+-*/': would handle the other operators.r'... denotes a raw string. We actually want to send those literal backslashes to the regular expression parser, so raw strings allow us to do this without a lot of backslash escaping.The simplest answer is to just replace all spaces with empty string:
"21 2 4 + 21 1".replace(' ', '') # DO NOT DO THIS
While actually the good answer is to check how you get the data and whether you can process it before. Also this one looks terribly insecure and can lead to tons of errors.
Just putting this up here for two reasons:
This is basically the same method, but takes into account additional operands [+, -, *, /], uses a lambda and it won't fail if operand doesn't exist in the string:
import re
s = ["12 3 65 + 42", "1 8 89 0 - 192", "145 7 82 * 2"]
map(lambda x: re.split("[\+\-\*\/]", x)[0].replace(" ", ""), s)
will output
['12365', '18890', '145782']
lambda is a little contrived in your example :) And I don't believe you need to escape special characters in [ ]s in the lambda when I should have used x. I thought so too (about escaping special characters in [ ]), but I get error: bad character range when I don't.A possible way would be to use itertools.takewhile() because it quite literally expresses your intent: "all numbers from 1-9 together before operand?"
from itertools import takewhile
# extract all characters until the first operator
def snip(x):
return takewhile(lambda x: x not in "+-*/", x)
# extract just the digits from the snipped string and
# make a string out of the characters
# **EDIT** filter expression changed to let _only_ digits
# 1-9 pass ...
def digits(x):
return ''.join( filter(lambda c: ord('1')<=ord(c)<=ord('9'), snip(x)) )
Proof of the pudding:
>>> print digits(" 1 22 hello + 3")
122
0 from the list of digits.