What do numbers starting with 0 mean in python?
Question:
When I type small integers with a 0 in front into python, they give weird results. Why is this?
>>> 011
9
>>> 0100
64
>>> 027
23
I’m using Python 2.7.3. I have tested this in Python 3.0, and apparently this is now an error. So it is something version-specific.
They are apparently still integers:
>>> type(027)
<type 'int'>
Answers:
These are numbers represented in base 8 (octal numbers).
Some examples:
Python 2 (old format)
Note: these forms only work on Python 2.x.
011
is equal to 1⋅8¹ + 1⋅8⁰ = 9,
0100
is equal to 1⋅8² + 0⋅8¹ + 0⋅8⁰ = 64,
027
is equal to 2⋅8¹ + 7⋅8⁰ = 16 + 7 = 23.
Python 3 (new format)
In Python 3, one must use 0o
instead of just 0
to indicate an octal constant, e.g. 0o11
or 0o27
, etc. Python 2.x versions >= 2.6 supports both the new and the old format.
0o11
is equal to 1⋅8¹ + 1⋅8⁰ = 9,
0o100
is equal to 1⋅8² + 0⋅8¹ + 0⋅8⁰ = 64,
0o27
is equal to 2⋅8¹ + 7⋅8⁰ = 16 + 7 = 23.
That is very easy. They are octal numbers.
http://en.wikipedia.org/wiki/Octal
Also there are numbers that are starting with 0x
. They are hexadecimal numbers:
>>> 0x51
81
These are octal numbers (base 8, values 0 – 7)
You can convert a decimal number to octal with the oct() function.
In [125]: for i in range(10):
.....: print '{:5} {:5}'.format(i, oct(i))
.....:
0 0
1 01
2 02
3 03
4 04
5 05
6 06
7 07
8 010
9 011
and convert an octal value to integer with the int() function with the appropriate base (8 in this case):
int(str(17), 8)
Out[129]: 15
The similar set of rules/functions apply for hexadecimal numbers (base 16) using the hex() function.
Numbers in Octal numerical system. Other prefixes are 0x
for hexadecimal and 0b
for binary.
In Python 2 (and a few more programming languages), these represent octal numbers.
In Python 3, 011
no longer works and you would use 0o11
instead.
In response to edit: and they are regular integers. They are just specified different way; and they are automatically converted by Python to an internal integer representation (which is base-2 actually, so both 9
and 011
are internally converted to 0b1001
).
They are apparently octal (base 8) numbers, and the 0 is just an outdated prefix that Python 2 used to use.
In Python 3 you must write: 0o11
instead.
They are still integers but doing operations with them will give a result in regular base-10 form.
Both Python versions 2 & 3 understand octal written with leading ‘0o’ and ‘0O’ (Uppercase o), so be in the habit of using if when working with Python 2.x as well.
Only use leading zeros in numbers in strings.
You can convert integers from any of the other base systems with int().
>>> int(0o20)
16
If you want your output to display with leading zeros, then define it per this answer:
Display number with leading zeros
If you ever plan to work with ZIP Codes, it’s best to treat them as strings in all ways.
I have tried it out. I have learned a little bit. From Java I know this as a pitfall: A leading zero introduces an octal number. I have colleagues which didn’t resp. don’t know that after more than years with experience in Java.
Now I was interesting what the behaviour in Python is. I appreciate that change from Python 2 to Python 3. It is pitfall I have never understood why Java (a young language with focus on “beeing easy”) could take over that stupid solution from C.
A leading zero as prefix can be accidentally typed (bad solution). 0x for a hexadecimal number is never accidentally typed (good solution). But 0 and o are to similar therefore I think 0o23 in Python is not a perfect solution. 0c23 (octal) would be a better solution in my opinion.
The latest Python specification for number literals is in PEP-3127 “Integer Literal Support and Syntax”
The syntax for 011 has been removed in Python 3.0. The syntax for 0o11 has been added in Python 2.6 and it is the only one supported after Python 3.0. There is no __future__
import in Python 2 that would disallow or atleast warn on number literals with leading zeros, so developers have to know what 011 means and that it should be avoided (and that it can actually be avoided).
When I type small integers with a 0 in front into python, they give weird results. Why is this?
>>> 011
9
>>> 0100
64
>>> 027
23
I’m using Python 2.7.3. I have tested this in Python 3.0, and apparently this is now an error. So it is something version-specific.
They are apparently still integers:
>>> type(027)
<type 'int'>
These are numbers represented in base 8 (octal numbers).
Some examples:
Python 2 (old format)
Note: these forms only work on Python 2.x.
011
is equal to 1⋅8¹ + 1⋅8⁰ = 9,
0100
is equal to 1⋅8² + 0⋅8¹ + 0⋅8⁰ = 64,
027
is equal to 2⋅8¹ + 7⋅8⁰ = 16 + 7 = 23.
Python 3 (new format)
In Python 3, one must use 0o
instead of just 0
to indicate an octal constant, e.g. 0o11
or 0o27
, etc. Python 2.x versions >= 2.6 supports both the new and the old format.
0o11
is equal to 1⋅8¹ + 1⋅8⁰ = 9,
0o100
is equal to 1⋅8² + 0⋅8¹ + 0⋅8⁰ = 64,
0o27
is equal to 2⋅8¹ + 7⋅8⁰ = 16 + 7 = 23.
That is very easy. They are octal numbers.
http://en.wikipedia.org/wiki/Octal
Also there are numbers that are starting with 0x
. They are hexadecimal numbers:
>>> 0x51
81
These are octal numbers (base 8, values 0 – 7)
You can convert a decimal number to octal with the oct() function.
In [125]: for i in range(10):
.....: print '{:5} {:5}'.format(i, oct(i))
.....:
0 0
1 01
2 02
3 03
4 04
5 05
6 06
7 07
8 010
9 011
and convert an octal value to integer with the int() function with the appropriate base (8 in this case):
int(str(17), 8)
Out[129]: 15
The similar set of rules/functions apply for hexadecimal numbers (base 16) using the hex() function.
Numbers in Octal numerical system. Other prefixes are 0x
for hexadecimal and 0b
for binary.
In Python 2 (and a few more programming languages), these represent octal numbers.
In Python 3, 011
no longer works and you would use 0o11
instead.
In response to edit: and they are regular integers. They are just specified different way; and they are automatically converted by Python to an internal integer representation (which is base-2 actually, so both 9
and 011
are internally converted to 0b1001
).
They are apparently octal (base 8) numbers, and the 0 is just an outdated prefix that Python 2 used to use.
In Python 3 you must write: 0o11
instead.
They are still integers but doing operations with them will give a result in regular base-10 form.
Both Python versions 2 & 3 understand octal written with leading ‘0o’ and ‘0O’ (Uppercase o), so be in the habit of using if when working with Python 2.x as well.
Only use leading zeros in numbers in strings.
You can convert integers from any of the other base systems with int().
>>> int(0o20)
16
If you want your output to display with leading zeros, then define it per this answer:
Display number with leading zeros
If you ever plan to work with ZIP Codes, it’s best to treat them as strings in all ways.
I have tried it out. I have learned a little bit. From Java I know this as a pitfall: A leading zero introduces an octal number. I have colleagues which didn’t resp. don’t know that after more than years with experience in Java.
Now I was interesting what the behaviour in Python is. I appreciate that change from Python 2 to Python 3. It is pitfall I have never understood why Java (a young language with focus on “beeing easy”) could take over that stupid solution from C.
A leading zero as prefix can be accidentally typed (bad solution). 0x for a hexadecimal number is never accidentally typed (good solution). But 0 and o are to similar therefore I think 0o23 in Python is not a perfect solution. 0c23 (octal) would be a better solution in my opinion.
The latest Python specification for number literals is in PEP-3127 “Integer Literal Support and Syntax”
The syntax for 011 has been removed in Python 3.0. The syntax for 0o11 has been added in Python 2.6 and it is the only one supported after Python 3.0. There is no __future__
import in Python 2 that would disallow or atleast warn on number literals with leading zeros, so developers have to know what 011 means and that it should be avoided (and that it can actually be avoided).