Section author: Robert Nikutta <robert.nikutta@noirlab.edu>
Version: 20211119
4.3. Python 3 vs Python 2¶
Support for Python 2 at Data Lab ended in October 2020. Python 3 is now mature, fast, and the default Python version for the foreseeable future. While all notebooks curated at Astro Data Lab use Python 3, some users may be still using older Python 2 versions. This page is meant to provide some guidance in how to make these older notebooks compatible with Python 3 and how to continue running them at Data Lab.
The required changes are likely minor. If after reading through this guide you still find yourself unable to run your notebook, please contact the team at datalab@noirlab.edu . We are here to help!
4.3.1. print()
is now a function in Python 3¶
Convert all your print statements from print "Hello world"
to
print("Hello world")
. Simple as that.
If your notebook starts with the line from __future__ import
print_function
, you should remove that line now.
4.3.2. No more xrange()
, use range()
instead¶
Python 2 supported both range()
and xrange()
functions to
construct a sequence of integers. range(10,16)
for instance
returned a list of integers [10,11,12,13,14,15]
, while
xrange(10,16)
returned an object that knew how to generate the
next integer between 10 and 15. range()
materialized the entire
sequence into memory (which can be a lot of data, if the MIN and MAX
values are far apart), while xrange()
only generated one number at
a time (much more memory efficient, but slower).
In Python 3 there is no more xrange()
, and range()
is the
object that knows how to make a list of integers. Plus, it’s now
fast. That is, always use range(10,16)
, and if you need the full
list at once, wrap the command inside a list()
function,
i.e. list(range(10,16)) --> [10,11,12,13,14,15]
.
4.3.3. Division operators¶
This one is potentially dangerous if your Python 2 notebook relied on
integer division. In Python 2 the division operator /
, when
applied to integers, returned the result of integer division, i.e. it
dropped the remainder:
# Python 2
10 / 3
3
In Python 3, the same expression returns a float:
# Python 3
10 / 3
3.333333333333333
To achieve a floating point result in Python 2, one had to cast one of the operands as float:
# Python 2
10 / 3.
3.333333333333333
# or
10 / float(3)
3.333333333333333
Python 3 does the casting automatically.
If you want integer division on Python 3, use the //
operator:
# Python 3 integer division
10 // 3
3
4.3.4. Strings and bytes¶
The implicit type of bytes in Python 2 is str, but in Python 3 str and bytes are different:
# Python 2: str and bytes are the same
type("Hello"), type(b"Hello")
(str, str)
# Python 3: str and bytes are different
type("Hello"), type(b"Hello")
(str, bytes)
If you need to convert a string to bytes in Python 3:
# Python 3
b"hello" --> is bytes
"Hello".encode() --> same
And if you need to convert a bytes sequence to str:
# Python 3
foo = b"Hello"
foo
b'Hello'
foo.decode()
Hello
4.3.5. More documentation of differences between Python 2 and 3¶
Many more examples and guides on the differences between Python 2 and 3 are described in many places on the internet. Learn about differences in handling exceptions, new-style string formatting, iterator methods, renamed modules, and much more, for instance here:
https://sebastianraschka.com/Articles/2014_python_2_3_key_diff.html https://docs.python.org/3/howto/pyporting.html http://ptgmedia.pearsoncmg.com/imprint_downloads/informit/promotions/python/python2python3.pdf