Why is it impossible to directly convert "1.7" to integer without first converting the float?

When you type int("1.7") Python returns an error (in particular, ValueError). I know that I can convert it to an integer by int(float("1.7")) . I would like to know why the first method returns an error.

+8
python floating-point type-conversion integer coercion
source share
4 answers

From the documentation :

If x is not a number or a base value is given, then x must be a string or a Unicode object representing an integer literal in the base ...

Obviously, "1.7" does not represent an integer literal in the base base.

If you want to know why the python developer decided to limit himself to integer literals in the radix base, there are an infinite number of reasons, and you will have to ask Guido et. to know for sure. One of them is ease of implementation + efficiency. You might think that it would be easy for them to implement it as:

  • Interpret the number as floating
  • truncate integer

Unfortunately, this does not work in python, since integers can have arbitrary precision, but float cannot. Large numbers of special enclosures can lead to inefficiency for general case 1 .

In addition, forceful execution of int(float(...)) has the added benefit of clarity - this makes it more obvious what the input line looks like, which can help debug elsewhere. In fact, I can argue that even if int would accept strings like "1.7" , it would be better to write int(float("1.7")) in any case to increase the clarity of the code.

1 Assuming some verification. Other languages ​​overlook this - for example. ruby will evaluate '1e6'.to_i and give you 1 , since it ceases to deal with the first non-integral character. It seems like this could lead to funny tracking errors ...

+9
source share

We have a good, obvious idea that “making an int out of this float” means because we think of the float as two parts, and we can throw away one of them.

This is not so obvious when we have a string. To make this line in a float implies all kinds of subtle things about the contents of the line, and this is not the thing that a sane person wants to see in code where the meaning is not obvious.

So the short answer is: Python loves the obvious things and discourages magic.

+2
source share

Here is a good description of why you cannot do this in the python documentation.

https://docs.python.org/2/library/functions.html#int

If x is not a number or a base value is specified, then x must be a string or a Unicode object representing an integer literal in the base database. Optionally, a literal can be preceded by + or - (without a space between them) and surrounded by spaces. The literal base-n consists of numbers from 0 to n-1, from a to z (or from A to Z), with values ​​from 10 to 35. The default base is 10. The allowed values ​​are 0 and 2-36. The letters Base-2, -8, and -16 can optionally be prefix 0b / 0B, 0o / 0O / 0, or 0x / 0X, like whole literals in code. Base 0 means interpreting the string exactly as an integer literal, so the actual base is 2, 8, 10, or 16.

Basically, to cast a type to an integer from a string, the string should not contain "."

+1
source share

Interrupts backward compatibility . it of course it’s possible, but that would be a terrible idea, as it would violate backward compatibility with the very old and well-established Python idiom relying on trying ... except for the ladder ("Easier to apologize than permission") to determine the type the contents of the string. This idiom has been around and has been used since at least Python 1.5, AFAIK; here are two quotes: [1] [2]

 s = "foo12.7" #s = "-12.7" #s = -12 try: n = int(s) # or else throw an exception if non-integer... print "Do integer stuff with", n except ValueError: try: f = float(s) # or else throw an exception if non-float... print "Do float stuff with", f except ValueError: print "Handle case for when s is neither float nor integer" raise # if you want to reraise the exception 

And one more minor thing: it's not only about whether the number contains '.' Scientific notation or arbitrary letters can also violate the integrity of a string. Examples: int("6e7") not an integer (base-10). However, int("6e7",16) = 1767 is an integer in the base 16 (or any base> = 15). But int("6e-7") never an int.

(And if you expand the base to base 36, any legal alphanumeric string (or Unicode) can be interpreted as representing an integer, but by default it will be terrible behavior, since a “dog” or “cat” is unlikely to be links by integers).

+1
source share

All Articles