Denise
Denise

Reputation: 49

Python- Trying to multiply items in list

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

Answers (5)

colidyre
colidyre

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

Curry
Curry

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

BlivetWidget
BlivetWidget

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

daniel451
daniel451

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

ptomato
ptomato

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

Related Questions