2

In the following code, I want to calculate the percent of G and C characters in a sequence. In Python 3 I correctly get 0.5, but on Python 2 I get 0. Why are the results different?

def gc_content(base_seq):
    """Return the percentage of G and C characters in base_seq"""
    seq = base_seq.upper()
    return (seq.count('G') + seq.count('C')) / len(seq)

gc_content('attacgcg')
davidism
  • 121,510
  • 29
  • 395
  • 339
calf
  • 861
  • 2
  • 11
  • 23
  • possible duplicate of [Python division](http://stackoverflow.com/questions/2958684/python-division) – Bakuriu Jul 08 '13 at 16:47

3 Answers3

9

/ is a different operator in Python 3; in Python 2 / alters behaviour when applied to 2 integer operands and returns the result of a floor-division instead:

>>> 3/2   # two integer operands
1
>>> 3/2.0 # one operand is not an integer, float division is used
1.5

Add:

from __future__ import division

to the top of your code to make / use float division in Python 2, or use // to force Python 3 to use integer division:

>>> from __future__ import division
>>> 3/2    # even when using integers, true division is used
1.5
>>> 3//2.0 # explicit floor division
1.0

Using either of these techniques works in Python 2.2 or newer. See PEP 238 for the nitty-gritty details of why this was changed.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • Is that a "best-practice" or gnibbler's first solution below "better?" – calf Jul 08 '13 at 16:50
  • This is best-practice. The work-around to use `float()` will work too, but it is basically a hack to avoid the issue. `from __future__ import division` is the correct way of handling this as Python 3 switches behaviour. – Martijn Pieters Jul 08 '13 at 16:51
  • Can `from __future__ import division` be used when using ipython? – calf Jul 08 '13 at 16:54
  • Yes, it works in ipython; it works in the standard Python console as well. – Martijn Pieters Jul 08 '13 at 16:54
2

In python2.x / performs integers division.

>>> 3/2
1

To get desired result you can change either one of the operands to a float using float():

>>> 3/2.      #3/2.0
1.5
>>> 3/float(2)
1.5

or use division from __future__:

>>> from __future__ import division
>>> 3/2
1.5
Ashwini Chaudhary
  • 244,495
  • 58
  • 464
  • 504
1

For Python2 / is integer division when the numerator and denominator are both int, you need to make sure to force floating point division

eg.

return (seq.count('G') + seq.count('C')) / float(len(seq))

alternatively, you can put

from __future__ import division

at the top of the file

John La Rooy
  • 295,403
  • 53
  • 369
  • 502