British geneticist interested in splicing, RNA decay, and synthetic biology. This is my blog focusing on my adventures in computational biology. 

Compbio 016: Practical Python for biologists - Moving from Python2 to Python3

Why move? 

I'm not going to lie, I put moving from Python2 to Python3 for longer than I should have. I just didn't see the point. I didn't understand enough about programming languages to get most of the details (for details, see here). BUT, important packages for scientific Python, including numpy and matplotlib, are dropping support for Python2 in 2018; new features will not be available to users of Python2 - NOW is the time to move to Python3. 

So even if your university course only covered Python2, like mine did, you don't want to be left behind using outdated packages! Make a promise to yourself "from this day forward, I will only write new code in Python3". I ended up finding the transition mostly trauma free, and with this guide, the transition cost should be near zero (if not, leave comments explaining what I can add to the post). There are Python packages to automate the transition of old code to Python3 (here and here) and the Python Converter website where you can simply copy-paste old code to get new ( But the aim of this post is to aid your understanding and how to write new code yourself.

Some small changes

So something you might not have realized, but in Python2, string data represented both the text data type and the binary data type. This could cause problems with code. So this was eliminated in Python3: now all text (string) is Unicode. Support for Unicode finally means non-Roman characters are supported as default, which is great! 

Another change to be aware of: in Python3, 5 / 2 == 2.5 and not 2. If you miss this feature, you can instead do 5 // 2 == 2, but personally I won't miss this.  


In Python2, to print something to the terminal, you simply typed in the print statement as so: 

$ print "Hello world"
Hello world

In Python3, print is now a function, so you need to include parentheses like so: 

$ print("Hello world")
Hello world

I was a little frustrated with the extra typing involved but I quickly got over it. Plus, print being a function makes the language more internally consistent. 

To write to an outfile in Python2 (eg a list stored as the variable 'line'), I would do this in Python2: 

$ print >>outfile, "\t".join(line) 

In Python3, what we want to do instead is us the write() function like so: 

$ outfile.write('\t'.join(line) + '\n')

print operators

In the past, if you wanted a value to be printed within a string, depending on what is stored in a value, you would do something like this: 

$ i = 3
$ s = "is a magic number"
$ print "%d %s" % (i, s)
3 is a magic number

But in Python3, we now need to use str.format(): 

$ i = 3
$ s = "is a magic number"
$ print("{} {}".format(i, s))
3 is a magic number

I actually prefer this, it seems simpler. If you want to be more explicit with the printing of values fed into str.format(), you can use numbers like so: 

$ print("{0} {1}".format(i, s))
3 is a magic number
$ print("{0} {0}".format(i, s))
3 3


To iterate over a dictionary in Python2: 

$ for value in my_dict.itervalues():
$    ...

In Python3, you will want to do this: 

$ for value in my_dict.values(): 
$     ...

To go over keys and values in Python3, we want to do this: 

$ for (key, value) in my_dict.items():
$     ...

If there is anything vital that I am missing, please do get in touch and I will update the post.

If you want to do some more reading about Python3, its reason for existing and how to migrate over to it from Python2, here are some handy websites:

Compbio 017: Is your overlap significant?

Compbio 015: Practical Python for biologists - Processing two input files