Reputation: 49
So basically what I'm trying to do here is ask a user for a random string input, for example:
asdf34fh2
And I want to pull the numbers out of them into a list and get [3,4,2]
but I keep getting [34, 2]
.
import re
def digit_product():
str1 = input("Enter a string with numbers: ")
if str1.isalpha():
print('Not a string with numbers')
str1 = input("Enter a string with numbers: ")
else:
print(re.findall(r'\d+', str1))
digit_product()
And then I want to take that list of numbers and multiply them, and ultimately get 24.
Upvotes: 4
Views: 184
Reputation: 4666
Here is a handy one-liner
print(reduce(lambda x, y: x * y, [int(n) for n in text_input if n.isdigit()]))
without the need to import re
. You should avoid importing resources if you can do it with built-in functions.
Also avoid using str
as a variable name. It's reserved for type string.
The reduce(lambda …
part is hard to get at the beginning. But you can just use it to multiply all items in list.
Algorithm Explanation
First, all elements (characters) in the input string are checked. If a digit was detected it will be appended to a list as an integer. Then the list will be reduced to the factor of all elements inside.
You said nothing about a zero value. Take care of it, e.g.
print(reduce(lambda x, y: x * y, [int(n) for n in text_input if n.isdigit() and n is not '0']))
Upvotes: 0
Reputation: 895
import re
import functools
def digit_product():
str=input("Enter a string with numbers: ")
finded = re.findall(r'\d', str)
if not finded:
print('Not a string with numbers')
else:
return functools.reduce(lambda x, y: int(x) * int(y), finded)
def digit_product2():
input_text = input("Enter a string with numbers: ")
return functools.reduce(lambda x, y: int(x) * int(y), filter(str.isdigit, input_text))
>>> digit_product()
Enter a string with numbers: a2s2ddd44dd
64
>>> digit_product2()
Enter a string with numbers: a2s2ddd44dd
64
Upvotes: 0
Reputation: 11063
Easiest to just use a comprehension, if you ask me.
>>> a = "asdf34fh2"
>>> [i for i in a if i in '0123456789']
['3', '4', '2']
or
>>> [i for i in a if i.isdigit()]
['3', '4', '2']
Upvotes: 0
Reputation: 11002
Regular expressions are dead slow and often tricky to handle. For your purpose I would recommend built-in functional programming and list expressions:
In [115]: a = "asdf34fh2gh39qw3409sdgfklh"
In [116]: filter(lambda x: x.isdigit(), a)
Out[116]: '342393409'
In [117]: [char for char in filter(lambda x: x.isdigit(), a)]
Out[117]: ['3', '4', '2', '3', '9', '3', '4', '0', '9']
Upvotes: -1
Reputation: 57850
Your regular expression, \d+
, is the culprit here. The +
means it matches one or more consecutive digits (\d
):
asdf34fh2
^- ^
\ \_ second match: one or more digits ("2")
\____ first match: one or more digits ("34")
It looks like you only want to match one digit, so use \d
without the +
.
Upvotes: 7