Format truncated Python float as int in string

Question:

A quick no-brainer:

some_float = 1234.5678
print '%02d' % some_float  # 1234

some_float = 1234.5678
print '{WHAT?}'.format(some_float) # I want 1234 here too

Note: {:.0f} is not an option, because it rounds (returns 1235 in this example).

format(..., int(some_float)) is exactly the thing I’m trying to avoid, please don’t suggest that.

Asked By: georg

||

Answers:

This works:

from math import trunc
some_float = 1234.5678

print '{:d}'.format(trunc(some_float))
=> 1234

Or just do this, for that matter:

print trunc(some_float)
=> 1234

I think it’s an acceptable answer, it avoids the conversion to int. Notice that in this snippet: '%02d' % some_float an implicit conversion to int is happening, you can’t avoid some sort of conversion for printing in the desired format.

Answered By: Óscar López

It’s possible to extend the standard string formatting language by extending the class string.Formatter:

class MyFormatter(Formatter):
    def format_field(self, value, format_spec):
        if format_spec == 't':  # Truncate and render as int
            return str(int(value))
        return super(MyFormatter, self).format_field(value, format_spec)

MyFormatter().format("{0} {1:t}", "Hello", 4.567)  # returns "Hello 4"
Answered By: bereal

This will work too:

some_float = 1234.5678
f = lambda x: str(x)[:str(x).find('.')]
print '{}'.format(f(some_float))
=> 1234

After doing a %timeit test it looks like this is a bit faster than the trunc method.

Answered By: John Volk

It’s worth mentioning the built in behavior for how floats are rendered using the raw format strings. If you know in advance where your fractional part lies with respect to 0.5 you can leverage the format string you originally attempted but discovered it fell short from rounding side effects "{:0.0f}". Check out the following examples…

>>> "{:0.0f}".format(1.999)
'2'
>>> "{:0.0f}".format(1.53)
'2'
>>> "{:0.0f}".format(1.500)
'2'
>>> "{:0.0f}".format(1.33)
'1'
>>> "{:0.0f}".format(0.501)
'1'
>>> "{:0.0f}".format(0.5)
'0'
>>> "{:0.0f}".format(0.1)
'0'
>>> "{:0.0f}".format(0.001)
'0'

As you can see there’s rounding behavior behind the scenes. In my case where I had a database converting ints to floats I knew I was dealing with a non fractional part in advance and only wanted to render in an html template the int portion of the float as a workaround. Of course if you don’t know in advance the fractional part you would need to carry out a truncation operation of some sort first on the float.

Answered By: jxramos
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.