.. sectionauthor:: Robert Nikutta *Version: 20211119* .. index:: single: Python3 single: Python2 .. _sec_Python3vs2: ******************** 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! ``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. 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]``. 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: .. code-block:: python # Python 2 10 / 3 3 In Python 3, the same expression returns a float: .. code-block:: python # 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: .. code-block:: python # 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: .. code-block:: python # Python 3 integer division 10 // 3 3 Strings and bytes ----------------- The implicit type of bytes in Python 2 is str, but in Python 3 str and bytes are different: .. code-block:: python # 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: .. code-block:: python # Python 3 b"hello" --> is bytes "Hello".encode() --> same And if you need to convert a bytes sequence to str: .. code-block:: python # Python 3 foo = b"Hello" foo b'Hello' foo.decode() Hello 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