pylang pylang - 4 months ago 14
Python Question

Python: How to efficiently reformat numeric strings?

UPDATE: This question has been revised for clarity. The accepted answer addressed the original question, which included a precision requirement. This requirement has since been removed.

REVISED: I have a regex function that pulls numbers from any string creating a "numeric string". For each numeric string, I want a separate function that reformats them to appear float-like. Example:

format_str("23.05")
"23.05"

format_str("23")
"23.0"


The latter example illustrates the must significant conversion, from int-like to float-like, which effectively appends
".0"
to an int-like string. Float-like strings may remain unchanged.

Here is a sample of numeric strings, comprising integer and float-like values:

import numpy as np

# Build a random sampling of integers and floats
size = 100000
float_arr = np.random.uniform(1, 5000, size=size/2.)
integer_arr = np.random.randint(1, 5000, size=(size/2.))
mixed_set = set(float_arr) | set(integer_arr)
numeric_strs = list(str(num) for num in mixed_set)


Here is a test:

def test_equiv_strs(func, numeric_strs):
"""Verify the function has the same result as type-conversion operation."""
for num_str in numeric_strs:
actual = func(num_str)
expected = str(float(num_str)) # double type converstion
nt.assert_equal(actual, expected)
nt.assert_is_instance(actual, str)
#print("Orig. {}, Non-convert {}, Conversions {}".format(num_str, actual, expected))

test_equiv_strs(format_str, numeric_strs)


In Python, how do I most efficiently format numeric strings to float-like strings?




ORIGINAL: I want a function that formats numeric strings with a precision of one decimal. The function should return a string.

format_str("23")
"23.0"

format_str("23.0")
"23.0"


Note: I know the following works, but I prefer to avoid type conversions, i.e.
str
to
float
to
str
.

def format_str(number):
return "{:.1f}".format(float(number))


How do I accomplish this in Python without converting the string type?

Answer

You can use partition with '.' as separator:

def format_str(number):
    r, _, l = number.partition('.')
    return r + '.' + (l[0] if l else '0')

Trial:

>>> format_str('23')
'23.0'
>>> format_str('23.0')
'23.0'
>>> format_str('23.')
'23.0'
>>> format_str('23.123')
'23.1'