Version number comparison in Python Version number comparison in Python python python

Version number comparison in Python


How about using Python's distutils.version.StrictVersion?

>>> from distutils.version import StrictVersion>>> StrictVersion('10.4.10') > StrictVersion('10.4.9')True

So for your cmp function:

>>> cmp = lambda x, y: StrictVersion(x).__cmp__(y)>>> cmp("10.4.10", "10.4.11")-1

If you want to compare version numbers that are more complex distutils.version.LooseVersion will be more useful, however be sure to only compare the same types.

>>> from distutils.version import LooseVersion, StrictVersion>>> LooseVersion('1.4c3') > LooseVersion('1.3')True>>> LooseVersion('1.4c3') > StrictVersion('1.3')  # different typesFalse

LooseVersion isn't the most intelligent tool, and can easily be tricked:

>>> LooseVersion('1.4') > LooseVersion('1.4-rc1')False

To have success with this breed, you'll need to step outside the standard library and use setuptools's parsing utility parse_version.

>>> from pkg_resources import parse_version>>> parse_version('1.4') > parse_version('1.4-rc2')True

So depending on your specific use-case, you'll need to decide whether the builtin distutils tools are enough, or if it's warranted to add as a dependency setuptools.


Remove the uninteresting part of the string (trailing zeroes and dots), and then compare the lists of numbers.

import redef mycmp(version1, version2):    def normalize(v):        return [int(x) for x in re.sub(r'(\.0+)*$','', v).split(".")]    return cmp(normalize(version1), normalize(version2))

This is the same approach as Pär Wieslander, but a bit more compact:

Here are some tests, thanks to "How to compare two strings in dot separated version format in Bash?":

assert mycmp("1", "1") == 0assert mycmp("2.1", "2.2") < 0assert mycmp("3.0.4.10", "3.0.4.2") > 0assert mycmp("4.08", "4.08.01") < 0assert mycmp("3.2.1.9.8144", "3.2") > 0assert mycmp("3.2", "3.2.1.9.8144") < 0assert mycmp("1.2", "2.1") < 0assert mycmp("2.1", "1.2") > 0assert mycmp("5.6.7", "5.6.7") == 0assert mycmp("1.01.1", "1.1.1") == 0assert mycmp("1.1.1", "1.01.1") == 0assert mycmp("1", "1.0") == 0assert mycmp("1.0", "1") == 0assert mycmp("1.0", "1.0.1") < 0assert mycmp("1.0.1", "1.0") > 0assert mycmp("1.0.2.0", "1.0.2") == 0


Is reuse considered elegance in this instance? :)

# pkg_resources is in setuptools# See http://peak.telecommunity.com/DevCenter/PkgResources#parsing-utilitiesdef mycmp(a, b):    from pkg_resources import parse_version as V    return cmp(V(a),V(b))