5

Forgive me, I'm new to Python.

Given a string that starts with a float of indeterminate length and ends with the same, how can I extract both of them into an array, or if there is just one float, just the one.

Example:

"38.00,SALE ,15.20"
"69.99"

I'd like to return:

[38.00, 15.20]
[69.99]
3
  • This is rather imprecise: your example shows "SALE" which you don't say any thing about in your question. What exactly is your input like? Commented Oct 15, 2016 at 3:56
  • Is your input always comma separated Commented Oct 15, 2016 at 3:56
  • more input examples needed Commented Oct 15, 2016 at 4:04

7 Answers 7

7

You could also use regex to do this

import re
s = "38.00,SALE ,15.20"
p = re.compile(r'\d+\.\d+')  # Compile a pattern to capture float values
floats = [float(i) for i in p.findall(s)]  # Convert strings to float
print floats

Output:

[38.0, 15.2]
Sign up to request clarification or add additional context in comments.

2 Comments

Don't use regex in python when you have a more readable alternative available.
I agree, but it tends to work well for cases where strings are not properly defined and are a bit free form. Also, this simple case is a good way to learn if the OP is not familiar already :)
2
def extract_nums(text):
    for item in text.split(','):
        try:
            yield float(item)
        except ValueError:
            pass

print list(extract_nums("38.00,SALE ,15.20"))
print list(extract_nums("69.99"))

[38.0, 15.2]
[69.99]

However by using float conversion you are losing precision, If you want to keep the precision you can use decimal:

import decimal

def extract_nums(text):
    for item in text.split(','):
        try:
            yield decimal.Decimal(item)
        except decimal.InvalidOperation:
            pass

print list(extract_nums("38.00,SALE ,15.20"))
print list(extract_nums("69.99"))

[Decimal('38.00'), Decimal('15.20')]
[Decimal('69.99')]

4 Comments

I'd say using csv is overkill for grabbing a couple of floats with known position in a string.
@machineyearning I never used csv, where did you see me using it? Were you reading my mind?
oh weird, I guess I didn't read your answer closely enough, but the first code snippet starts with import csv hahahaha.
@machineyearning Oh you're right let me remove that. And great joke
1

You said you're only interested in floats at the start and end of the string, so assuming it's comma-delimited:

items = the_string.split(',')
try:
    first = float(items[0])
except (ValueError, IndexError):
    pass
try:
    second = float(items[-1])
except (ValueError, IndexError):
    pass

We have to wrap the operations in exception handlers since the value might not be a valid float (ValueError) or the index might not exist in the list (an IndexError).

This will handle all cases including if one or both of the floats is omitted.

Comments

0

You can try something like

the_string = "38.00,SALE ,15.20"
floats = []
for possible_float in the_string.split(','):
    try:
        floats.append (float (possible_float.strip())
    except:
        pass
print floats

4 Comments

you shouldn't use naked except-clauses
also what about the case "here's a float: 123.45, and here's another: 67.89"
@JulienBernu according to the question the floats only occur at the beginning and end of the string.
You don't need a for loop if you know beforehand there are only 2 values of interest. Just extract the 2 values from where you know they are.
0

Try a list comprehension:

just_floats = [i for i in your_list.split(',') if i.count('.') == 1]

first you split the string where the commas are, then you filter through the string and get rid of values that don't have a decimal place

1 Comment

Not all strings containing a period are floats.
0
import re    
map(float, filter(lambda x: re.match("\s*\d+.?\d+\s*", x) , input.split(","))

Input : input = '38.00,SALE ,15.20' Output: [38.0, 15.2]

Input : input = '38.00,SALE ,15.20, 15, 34.' Output: [38.0, 15.2, 15.0, 34.0]

Explanation:

  1. Idea is to split the string : list_to_filter = input.split(",") splits on ,
  2. Then using regex filter strings which are real numbers: filtered_list = filter(<lambda>, list_to_filter) , here item is included in output of filter if lamda expression is true. So when re.match("\s*\d+.?\d+\s*", x) matches for string x filter keeps it.
  3. And finally convert into float. map(float, filtered_list). What it does is apply float() function to each element of the list

2 Comments

That's really hard to read and unpythonic. There's no reason to put it all on one line. Especially since the OP said he's new to python, you should make an effort to make your answer readable and understandable.
Yes I agree, added explanation for clarity. Since he is new, that one line could expose him to new concepts too :)
0

Split the input, check if each element is numeric when the period is removed, convert to float if it is.

def to_float(input):
    return [float(x) for x in input.split(",") if unicode(x).replace(".", "").isdecimal()]

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.