Numeric coercions

Joshua Landau joshua.landau.ws at gmail.com
Sun Jul 7 00:17:01 EDT 2013


On 7 July 2013 04:56, Steven D'Aprano
<steve+comp.lang.python at pearwood.info> wrote:
> I sometimes find myself needing to promote[1] arbitrary numbers
> (Decimals, Fractions, ints) to floats. E.g. I might say:
>
> numbers = [float(num) for num in numbers]
>
> or if you prefer:
>
> numbers = map(float, numbers)
>
> The problem with this is that if a string somehow gets into the original
> numbers, it will silently be converted to a float when I actually want a
> TypeError. So I want something like this:
>
> def promote(x):
>     if isinstance(x, str): raise TypeError
>     return float(x)
>
> but I don't like the idea of calling isinstance on every value. Is there
> a better way to do this? E.g. some operation which is guaranteed to
> promote any numeric type to float, but not strings?
>
> For the record, calling promote() as above is about 7 times slower than
> calling float in Python 3.3.

>>> from operator import methodcaller
>>> safe_float = methodcaller("__float__")
>>> safe_float(434)
434.0
>>> safe_float(434.4342)
434.4342
>>> safe_float(Decimal("1.23"))
1.23
>>> safe_float("123")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute '__float__'
>>>



More information about the Python-list mailing list