Migrating from Python2 to Python3

mar. 19 avril 2016 by Rémi Duraffort

Porting code from Python 2 to Python 3 is made easier by using 2to3. This application will find patterns that should be changed to keep the same behavior in Python 2 and 3.

However, 2to3 is sometime too conservative, trying to keep the exact same semantic.

For instance, dictionaries functions .items(), .keys() and .values() now (as in Python 3) return a view and not a list.

d = {'foo' : 'bar', 'bla': 'blo'}
keys = d.keys()
type(keys)
<type list>

While in Python 3

d = {'foo' : 'bar', 'bla': 'blo'}
keys = d.keys()
type(keys)
<class dict_keys>

If you run 2to3 on this snippet, you will get:

d = {'foo' : 'bar', 'bla': 'blo'}
keys = list(d.keys())
type(keys)
<type list>

This change guarantee that the semantic is exactly the same. However this change is often unneeded. In fact, the dict_keys class implement __iter__, __contains__ and __len__.

We can use the dict_keys in a for loop:

d = {1: 'one', 2: 'two', 3: 'three'}
for k in d.keys():
    print(k)
1
2
3

We can also check that a given key exists in the dictionary:

d = {1: 'one', 2: 'two', 3: 'three'}
if 2 in d.keys():
    print("Found")
found

While maintaining the same semantic, transforming the class into a list can waste many CPU cycles.