w3resource logo
Python Tutorial

Python 2 vs 3

Comparison between Python 2 and Python 3

The final 2.x version 2.7 release came out in mid-2010, with a statement of extended support for this end-of-life release. Python 3.0 was released in 2008. The 2.x release will see no new major releases after that. 3.x is under active development and has already seen over several years of stable releases, including version 3.3 in 2012, 3.4 in 2014, and 3.5 in 2015.

If you're new to programming or an experienced developer, it's easy to learn and use Python 3. Python 3 represents the future of the language as all development has stopped with Python 2.x, save for security and bugfixes.

Contents :

print statement vs. print function

In Python 3 the print statement has been replaced with a print() function, with keyword arguments to replace most of the special syntax of the old print statement.

Python 2 Python 3
>>> print "Hello World"
Hello World
>>> print("Hello World")
Hello World
>>> #print a newline
>>> print

>>> #print a newline,
>>> #using parentheses
>>> print()
  
>>> #add trailing comma to
>>> #remove newline
>>> print "No newline", 
    No newline
>>> #Appends nothing 
>>> #instead of a newline
>>> print("No newline", end="")
 No newline
>>> 
>>> #print to stderr
>>> print >>sys.stderr, "Error"   
  Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'sys' is not defined
>>> #Specifies the 
>>> #output buffer
>>>print("Error", file=sys.stderr)
>>> 
Traceback (most recent call last):
File "C:/Python34/test.py", 
 line 1, in <module>
 print("Error", file=sys.stderr)
 NameError: name 'sys' 
 is not defined
>>>
 
>>> #sep specifies the separator
>>> #here ',' is used as a separator
>>> print("Python", "JS", sep=",")
          Python,JS
 
>>> #prints as XYZ, there
>>> #is nothing in sep
>>> print("X", "Y", "Z", sep="")
    XYZ
 
>>> #flush the output buffer
>>> print("Python", flush=True)
  Python

Differences between range and xrange functions

Python 2 Python 3
>>> range(1, 10)
   [1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> range(1, 10)
   range(1, 10)
>>> 
>>> xrange(1, 10)
xrange(1, 15)
>>> xrange(1, 10)
  Traceback (most recent call last):
File "<pyshell#9>", 
line 1, in <module>
xrange(1, 10)
NameError: name 'xrange' 
is not defined
      
>>> isinstance(xrange(1, 15), xrange)
True
>>>
>>> isinstance(range(1, 15), range)
True
>>> 

Raising and handling Exceptions

Python 2 Python 3
>>> 3 < 5.5
    True
>>>
	>>> 3 < 5.5
True
>>>
>>> [3, 5] > 'xyz'
      False
>>>
>>> [3, 5] > 'xyz'
 Traceback (most recent call last):
 File "<pyshell#14>", 
 line 1, in <module>
 [3, 5] > 'xyz'
TypeError: unorderable types: 
list() > str()
>>>
>>> (3, 5) > 'xyz'
   True
>>>
>>> (3, 5) > 'xyz'
Traceback (most recent call last):
File "<pyshell#15>", 
line 1, in <module>
(3, 5) > 'xyz'
TypeError: unorderable types: 
tuple() > str()>>> 
>>> [3, 5] > (3, 5)
      False
>>>
>>> [3, 5] > (3, 5)
  Traceback (most recent call last):
File "<pyshell#21>", 
line 1, in <module>
[3, 5] > (3, 5)
TypeError: unorderable types: 
list() > tuple()
>>>
>>> 50 < [2, 'x'] < 'xyz' < (2, 'x')
	   True
>>>
>>> 50 < [2, 'x'] < 'xyz' < (2, 'x')
  Traceback (most recent call last):
File "<pyshell#23>", 
line 1, in <module>
50 < [2, 'x'] < 'xyz' < (2, 'x')
TypeError: unorderable types: 
int() < list()
>>>

Comparison of unorderable types

Python 2 Python 3
>>> print "[2, 3]>'xyz'= ", [2, 3]>'xyz'
[2, 3]>'xyz' =  False
>>> print "(2, 3)>'xyz' = ", (2, 3)>'xyz'
(2, 3)>'xyz' =  True
>>> print "[2, 3]>(2, 3) = ", [2, 3]>(2, 3)
[2, 3] > (2, 3) =  False
print("[1, 2]>'foo' = ", [1, 2]>'foo')
print("(1, 2)>'foo' = ", (1, 2)>'foo')
print("[1, 2]>(1, 2) = ", [1, 2]>(1, 2))
Traceback (most recent call last):
  File "C:/Python34/test.py", line 1, 
  in 
    print("[1, 2] > 'foo' = ", 
	[1, 2] > 'foo')
TypeError: unorderable types: 
list() > str()

bytes vs string

Python 2 Python 3
>>> a = "Python"
>>> len(a)
    6
>>> a[0]
    'P'
>>>
>>> a = "Python"
>>> len(a)
   6
>>> a[0]
   'P'
>>>
 
>>> 
#To treat a string as a 
#sequence of bytes, 
#you need to cast:
>>> a = bytes("Python", "utf-8")
>>> a
   b'Python'
>>> a[0]
   80
>>>
 
>>> #bytes(foo, 'utf-8') means to encode <em>foo</em>
>>> #in UTF-8. treat the result as a 
>>> #sequence of unsigned  8bit integers. You can 
>>> #also convert bytes to a string,
>>> #as following
>>> a = bytes("Python", "utf-8")
>>> b = str(a, "utf-8")
>>> b
    'Python'
>>>

Integer division

Python 2 Python 3
>>> import sys
>>> print(sys.version)
       2.7.9 (default, Apr  2 2015, 
	   15:33:21)[GCC 4.9.2]
>>> print "6/3 =", 6/3
    6/3 = 2
>>> print "6//3 =", 6//3
    6//3 = 2
>>> print "6/3.0 =", 6/3.0
    6/3.0 = 2.0
>>> print "6//3.0 =", 6//3.0
    6//3.0 = 2.0
>>>
>>> import sys
>>> print(sys.version)
       3.4.2 (v3.4.2:ab2c023a9432, 
	    Oct  6 2014, 22:15:05)
	    [MSC v.1600 32 bit (Intel)]
>>>
>>> print("6/3 =", 6/3)
    6/3 = 2.0
>>> print("6//3 =", 6//3)
    6//3 = 2
>>> print("6/3.0 =", 6/3.0)
    6/3.0 = 2.0
>>> print("6//3.0 =", 6//3.0)
    6//3.0 = 2.0
>>> 

Unicode

Python 2 has ASCII str() types, separate unicode(), but no byte type and in Python 3.0, the language features a str type that contain Unicode characters,

Python 2 Python 3
>>> import sys
>>> print(sys.version)
   2.7.9 (default, Apr  2 2015, 
   15:33:21) GCC 4.9.2]
>>> print type(unicode
("Python Unicode"))
<type 'unicode'>
>>>
>>> import sys
>>> print(sys.version)
  3.4.2 (v3.4.2:ab2c023a9432,
   Oct  6 2014, 22:15:05) 
   MSC v.1600 32 bit (Intel)]
>>>
>>> print type(b"Python")
   <type 'str'>
>>>
 
>>> print "Python" + b" Unicode"
Python Unicode
>>>
>>> print(" Python", type(b" Unicode"))
Python <class 'bytes'>
>>>

dictionary method

In Python 2
dict.iteritems(): Return an iterator over the dictionary's (key, value) pairs.

In Python 3
dict.items(): Return a copy of the dictionary’s list of (key, value) pairs.

Python 2 Python 3
>>> x = {1: "red", 2: "blue"}
>>> print(x)
   {1: 'red', 2: 'blue'}
>>> print(x.items())
dict_items([(1, 'red'), (2, 'blue')])
>>> print(x.iteritems())
    Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'dict' object has no 
attribute 'iteritems'
>>> print([i for i in x.iteritems()])
 [(1, 'red'), (2, 'blue')]
>>>
>>> x = {1: "red", 2: "blue"}
>>> print(x)
  {1: 'red', 2: 'blue'}
>>> print(x.items)
<built-in method items of dict object 
at 0x7fe191a89748>
>>> print(x.items())
dict_items([(1, 'red'), (2, 'blue')])
>>> print([i for i in x.items()])
  [(1, 'red'), (2, 'blue')]
>>>
   

For other dictionary methods: dict.keys, dict.values and dict.items return a list in Python 2, but in Python 3 they return a view object.

>>> #In Python 2 dict.has_key()
 is used to test.
>>> #whether the dict has 
a certain key.
>>> x = {1: "red", 2: "blue"}
>>> print(x.has_key(1))
True
>>>
>>> #But this method has been
>>> #removed in Python 3.
>>> #Instead, the in operator
>>> #Is used.
>>> x = {1: "red", 2: "blue"}
>>> print(a.has_key(1))
 #Don't run it, unless you want this:
 Traceback (most recent call last):
 File "<stdin>", line 1, in <module> 
 AttributeError: 'dict' object has
 no attribute 'has_key'
>>> print(1 in x)
        True
>>>

Data Input

Python 2 :
raw_input([prompt]) - If the prompt argument is present, it is written to standard output without a trailing newline. The function then reads a line from input, converts it to a string (stripping a trailing newline), and returns that. When EOF is read, EOFError is raised.

Python 3 :
input([prompt]) - If the prompt argument is present, it is written to standard output without a trailing newline. The function then reads a line from input, converts it to a string (stripping a trailing newline), and returns that. When EOF is read, EOFError is raised.

Python2 Python3
>>>data_input2 = raw_input()
>>>data_input3 = input()