I want to convert number 168 to binary using int,
It report error
In [11]: int(168, base=2)
----> 1 int(168, base=2)
TypeError: int() can't convert non-string with explicit base
I read the doc and tried alternativly
In [13]: int("168", base=2)
ValueError: invalid literal for int() with base 2: '168'
I learned that bin could get the job done
In [16]: bin(168)
Out[16]: '0b10101000'
How could I use int to do it?
The purpose of int with base=2 is to convert a string value in a given base (binary for base=2) to integer and not vice versa to convert into binary what you are trying to do.
From the docs
Return an integer object constructed from a number or string x, or return 0 if no arguments are given. If x is not a number or if base is given, then x must be a string, bytes, or bytearray instance representing an integer literal in radix base.
You can only use int() to convert things to an integer, the simplest way of converting from number to binary is the function bin(). Just so you know, int() can also convert binary to an integer.
Related
my quantity dtype is object (from csv file) and I am trying to covert to int using below code:
df[x1] = df[x1].astype(str).astype(int)
It throws error as below:
ValueError: invalid literal for int() with base 10: '1,000.000'
Can anyone help me in this please?
You need to remove ',' and '.'. You can use str.replace method to remove the comma and then cast the data to type float then to type int.
df[x1] = df[x1].str.replace(',','').astype(float).astype(int)
For example, for a Series such as
srs = pd.Series(['1,000.00','1'])
if you cast it to dtype int
srs.astype(int)
you get
ValueError: invalid literal for int() with base 10: '1,000.00'
Then if you remove the comma str.replace method and cast to dtype int
srs = srs.str.replace(',','')
srs.astype(int)
you get
ValueError: invalid literal for int() with base 10: '1000.00'
So you cast it to dtype float and to dtype int,
srs = srs.str.replace(',','').astype(float).astype(int)
you get the expected outcome:
0 1000
1 1
dtype: int32
You can use lambda functions!
df[x1] = df[x1].apply(lambda x: int(x))
Actually int() function expects an integer string or a float, but not a float string. If a float string is given you need to convert it to float first then to int as:
int(float(userGuess))
So you have to convert it to float first and then to int.
Why do I get an error When I tried to use int() function to convert a float to integer?
>>> int('99.99')
Traceback (most recent call last):
File "<pyshell#27>", line 1, in <module>
int('99.99')
ValueError: invalid literal for int() with base 10: '99.99'
I expected the result to be 99
Your argument isn't a float, it's a string containing the representation of a float. You have to convert it to a float first, then you can convert that to an int.
int(float('99.99'))
Per the docs
Return an integer object constructed from a number or string x, or
return 0 if no arguments are given. If x is a number, return
x.int(). For floating point numbers, this truncates towards zero.
If x is not a number or if base is given, then x must be a string,
bytes, or bytearray instance representing an integer literal in radix
base.
Pay particular attention to "representing an integer literal". So your str that you are attempting to convert cannot be a float, because that's a float literal, not an int literal.
So, as others have noted, you cannot go directly from a float literal to an int, you need to convert the float first:
x = '123.45'
int(float(x))
You are getting a ValueError because you are overloading int() with an argument that is not consistent with the Python docs.
According to the doc:
"If x is not a number or if base is given, then x must be a string or
Unicode object representing an integer literal "
Basically, x (in your case '99.99') is the string 99.99 which does not satisfy the requirements of being an integer literal. You provided a floating literal.
TL;DR
int(float('99.99'))
This works:
[IN] int(str(8))
[OUT] 8
This does not work:
[IN] int(bin(8))
[OUT] ValueError: invalid literal for int() with base 10: '0b1000'
[IN] int(hex(8))
[OUT] ValueError: invalid literal for int() with base 10: '0x8'
This is also weird:
[IN] bin(str(8))
[OUT] TypeError: 'str' object cannot be interpreted as an integer
# What are you telling me, Python?! You just did it with int()!
But:
[IN] float(str(8))
[OUT] 8.0
Even worse:
[IN] int(8.5)
[OUT] 8
[IN] int(str(8.5))
[OUT] ValueError: invalid literal for int() with base 10: '8.5'
[IN] float(str(8.5))
[OUT] 8.5 # IT WORKS??!
This makes int(some_string) a bad choice and instead int(float(some_string)) should be preferred!
Or:
[IN] hex(hex(8))
[OUT] TypeError: 'str' object cannot be interpreted as an integer
Bad design: A method that converts an object to the type it belongs to should always accept its own type as a valid input. (I know the type is str, but anyway).
[IN] complex(str(complex(8)))
[OUT] (8+0j)
# What are the rules again?
[IN] int(abs(complex(str(8.5))))
[OUT] 8
# OK... I guess?
This seems very anti-Pythonic to me. Is there a design reason why these very intuitive conversions don't work, or is it simply something that noone thought about and that needs to be improved? Or maybe I'm doing it the wrong way?
The only solution I found is
[IN] eval(hex(8))
[OUT] 8
[IN] eval(bin(8))
[OUT] 8
The int constructor accepts a second argument to specify the base that a first string argument should be interpreted in. So your examples with bin and hex would work if you specified base 2 and 16 respectively. Python won't use the prefix on the number to guess the base for you unless you specify the "special" base 0, which tells it to use the prefix to determine the base (otherwise appropriate prefixes are ignored and invalid ones cause exceptions). You can see that your issue is base related in the exception message, which specifically say the input values are not valid "for int() with base 10".
Similarly, Python won't implicitly truncate the fractional part of the string representation of a decimal value when creating an int. If you want to convert the string "8.5" to the integer 8, you need to first parse the string to a float (with e.g. val = float("8.5")), then convert the value to an integer, discarding the fractional part (e.g. int_val = int(val)). You can of course chain them together (int(float("8.5"))), but Python won't ever do the combined operation automatically for you.
I think you have a few fundamental misunderstandings here. Lets go through a couple of the various functions you called out. To start, lets look at int, and just try running help:
>>> help(int)
class int(object)
| int(x=0) -> int or long
| int(x, base=10) -> int or long
|
| Convert a number or string to an integer, or return 0 if no arguments
| are given. If x is floating point, the conversion truncates towards zero.
| If x is outside the integer range, the function returns a long instead.
|
| If x is not a number or if base is given, then x must be a string or
| Unicode object representing an integer literal in the given base. The
| literal can be preceded by '+' or '-' and be surrounded by whitespace.
| The base defaults to 10. Valid bases are 0 and 2-36. Base 0 means to
| interpret the base from the string as an integer literal.
| >>> int('0b100', base=0)
| 4
So int(foo) converts a string or number-type to an integer. Seems reasonable.
>>> help(bin)
bin(...)
bin(number) -> string
Return the binary representation of an integer or long integer.
And here bin(foo) converts an integer to a string (e.g.: "0b1010111")
Note that numbers in python are not bin or hex - those are bases. They are numbers, and can be stored as an int, float, long, etc. As a convenience to you the interpreter is happy to convert things like 1e6, 21.4, 0x12, 0777 into their respective number equivalent, but that doesn't mean that the numbers have "string" as a native format, or the base of the number that the representation was given is stored along with the value.
The root of your confusion seems to be that you are taking str as a first class object - perhaps because that is what is used to type code? The sentence (emphasis mine):
Bad design: A method that converts an object to the type it belongs to should always accept its own type as a valid input. (I know the type is str, but anyway).
Highlights this root.
To assume that bin would work for a string as well as an integer in python is somewhat silly, in the same way the expecting int("the smallest prime larger than the population of florida") is a bit silly. They do what they are documented to do.
A loose language such as Wolfram Alpha might take these in stride, while a strict language like Haskell might laugh at the concept of even allowing multiple types and argument counts for the same function.
For completeness:
bin('8'), hex('0x8') # Correctly rejects a non-integer
int('0b1000'), int('0x8'), int('8.5') # Correctly rejects non-integer string
int('0b1000', base=0), int('0x8', base=0) # Correctly performs slower interpretation depending on the string base
int('8.5', base=0) # Still correctly rejects non-integer string
int(8.5) # Correctly 'truncates a floating point towards 0'
eval(foo) # Please avoid use of eval, there are no common correct applications of this function
Highlighting this comment from Alan Leuthard:
There are two different int() functions. One accepts a single input
and is extremely fast. The other is slower and allows casting to
different bases. Efficiency of an often used built-in function is the
reason for the lack of features you want.
Let's see here:
This works:
[IN] int(str(8))
[OUT] 8 This does not work:
[IN] int(bin(8))
[OUT] ValueError: invalid literal for int() with base 10: '0b1000'
[IN] int(hex(8))
[OUT] ValueError: invalid literal for int() with base 10: '0x8'
There are no built-in hexadeximal or binary objects, only the string representations created by the built-in functions. You can always create them, if you'd like. So you're not casting from an int to a bin to an int, you're casting from a str to an int. Expecting the built-in int() function to recognize every string representation of a number is a bit much.
EDIT: I stand corrected, there's a second input to put a base. So int(hex(8), 16) would give you 8 and int(bin(8), 2) would also give you 8. Fancy that! Those Pythonistas think of everything...and now I learn a bit too!
This is also weird:
[IN] bin(str(8))
[OUT] TypeError: 'str' object cannot be interpreted as an integer
# What are you telling me, Python?! You just did it with int()!
bin() doesn't accept strings. Only integers. Write your own if you need it. It also only outputs a formatted string.
But:
[IN] float(str(8))
[OUT] 8.0
Yeah. Float accepts string representations of integers. bin() isn't as useful or as ubiquitous as float()
Even worse:
[IN] int(8.5)
[OUT] 8
[IN] int(str(8.5))
[OUT] ValueError: invalid literal for int() with base 10: '8.5'
[IN] float(str(8.5))
[OUT] 8.5 # IT WORKS??!
This makes int(some_string) a bad choice and instead int(float(some_string)) should be preferred!
Double casting (from a string to a float) in a single function is a bit much to ask. It requires int() to accept way too many inputs for a built-in function. The string has to be a representation of an int already. Simple and clear. And yes, if your string might be a float, cast it to a float first, then into an int. Not really much more work. You could always catch the exception, too!
Or:
[IN] hex(hex(8))
[OUT] TypeError: 'str' object cannot be interpreted as an integer Bad design: A method that converts an object to the type it belongs to
should always accept its own type as a valid input. (I know the type
is str, but anyway).
hex() creates a string. You answered your own question. If you want a Hex object, I believe there are several packages that implement them.
[IN] complex(str(complex(8)))
[OUT] (8+0j)
# What are the rules again?
[IN] int(abs(complex(str(8.5))))
[OUT] 8
# OK... I guess?
complex() takes a string representation of a complex as a valid input. That doesn't seem strange at all. Nor is it strange that int takes the absolute value of a complex (since all it has to do is ignore the imaginary part). Here, we see the effect of having an actual object implemented. Complex numbers are fully implemented in the built-in environment. Hex and Bin are not.
This seems very anti-Pythonic to me. Is there a design reason why
these very intuitive conversions don't work, or is it simply
something that noone thought about and that needs to be improved? Or
maybe I'm doing it the wrong way?
The only solution I found is
[IN] eval(hex(8))
[OUT] 8
[IN] eval(bin(8))
[OUT] 8
You can argue that Hex and Bin should be fully implemented objects in the built-in environment. But, currently, they aren't. Find a package that does it, or write your own objects.
I have an issue that really drives me mad. Normally doing int(20.0) would result in 20. So far so good. But:
levels = [int(gex_dict[i]) for i in sorted(gex_dict.keys())]
while gex_dict[i] returns a float, e.g. 20.0, results in:
"invalid literal for int() with base 10: '20.0'"
I am just one step away from munching the last piece of my keyboard.
'20.0' is a string, not a float; you can tell by the single-quotes in the error message. You can get an int out of it by first parsing it with float, then truncating it with int:
>>> int(float('20.0'))
20
(Though maybe you'd want to store floats instead of strings in your dictionary, since that is what you seem to be expecting.)
It looks like the value is a string, not a float. So you need int(float(gex_dict[i]))
It looks like the problem is that gex_dict[i] actually returns a string representation of a float '20.0'. Although int() has the capability to cast from a float to an int, and a string representation of an integer to an int. It does not have the capability to cast from a string representation of a float to an int.
The documentation for int can be found here:
http://docs.python.org/library/functions.html#int
The problem is that you have a string and not a float, see this as comparison:
>>> int(20.0)
20
>>> int('20.0')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: invalid literal for int() with base 10: '20.0'
You can workaround this problem by first converting to float and then to int:
>>> int(float('20.0'))
20
So it would be in your case:
levels = [int(float(gex_dict[i])) for i in sorted(gex_dict.keys())]
As the title says, in Python (I tried in 2.7 and 3.3.2), why int('0.0') does not work? It gives this error:
ValueError: invalid literal for int() with base 10: '0.0'
If you try int('0') or int(eval('0.0')) it works...
From the docs on int:
int(x=0) -> int or long
int(x, base=10) -> int or long
If x is not a number or if base is given, then x must be a string or Unicode object representing an integer literal in the given base.
So, '0.0' is an invalid integer literal for base 10.
You need:
>>> int(float('0.0'))
0
help on int:
>>> print int.__doc__
int(x=0) -> int or long
int(x, base=10) -> int or long
Convert a number or string to an integer, or return 0 if no arguments
are given. If x is floating point, the conversion truncates towards zero.
If x is outside the integer range, the function returns a long instead.
If x is not a number or if base is given, then x must be a string or
Unicode object representing an integer literal in the given base. The
literal can be preceded by '+' or '-' and be surrounded by whitespace.
The base defaults to 10. Valid bases are 0 and 2-36. Base 0 means to
interpret the base from the string as an integer literal.
>>> int('0b100', base=0)
4
Simply because 0.0 is not a valid integer of base 10. While 0 is.
Read about int() here.
int(x, base=10)
Convert a number or string x to an integer, or return
0 if no arguments are given. If x is a number, it can be a plain
integer, a long integer, or a floating point number. If x is floating
point, the conversion truncates towards zero. If the argument is
outside the integer range, the function returns a long object instead.
If x is not a number or if base is given, then x must be a string or
Unicode object representing an integer literal in radix base.
Optionally, the literal can be preceded by + or - (with no space in
between) and surrounded by whitespace. A base-n literal consists of
the digits 0 to n-1, with a to z (or A to Z) having values 10 to 35.
The default base is 10. The allowed values are 0 and 2-36. Base-2, -8,
and -16 literals can be optionally prefixed with 0b/0B, 0o/0O/0, or
0x/0X, as with integer literals in code. Base 0 means to interpret the
string exactly as an integer literal, so that the actual base is 2, 8,
10, or 16.
What you are trying to do is convert a string literal to an int. '0.0' can't be parsed to an integer because it contains a decimal point and therefore is unparseable as an integer.
However, if you use
int(0.0)
or
int(float('0.0'))
it will correctly parse.
If you must, you might use
int(float('0.0'))
you will need to convert the int to a float using this code:
test = 0 testrun = float(int(test)) print(testrun)
output: testrun = 0.0