Compare Version Numbers
Compare dotted version strings numerically per chunk: return −1, 0, or 1. "1.01" == "1.001", "1.0" == "1".
Intuition
Split on dots and compare chunk-by-chunk as integers — int() eats leading zeros for free. Different lengths? Missing chunks count as 0, so pad the shorter side conceptually.
The trap is treating a version as a number or a string; it's neither — it's a sequence of integers compared left to right. Once you see it that way, the two remaining questions answer themselves: parse each part as an int (killing leading zeros), and treat missing trailing parts as 0 so 1.0 and 1 compare equal.
Approach
Chunks, not characters
"1.10" > "1.9" numerically though it's smaller lexicographically — so convert each chunk with int().
Walk to the longer length
Iterate max(len(a), len(b)) chunks, treating absent ones as 0 — that's how "1.0" equals "1".
First difference decides
Return on the first unequal pair; equal all the way → 0.
Solution & live demo
Common pitfalls
Comparing the strings directly
return (version1 > version2) - (version1 < version2)
a = [int(x) for x in version1.split(".")]Lexicographic order puts "1.10" before "1.9" because '1' < '9', and "01" differs from "1". Parsing to integers is what makes 10 rank above 9 and leading zeros vanish.
Parsing as a float
if float(version1) > float(version2):
for i in range(max(len(a), len(b))):
A version can have more than one dot — float("1.2.3") raises, and even with one dot 1.10 becomes 1.1, ranking it below 1.9. Each component is independent, not a decimal fraction.
Stopping at the shorter version
for i in range(min(len(a), len(b))):
for i in range(max(len(a), len(b))):
x = a[i] if i < len(a) else 0
y = b[i] if i < len(b) else 01.0.1 versus 1 must report greater, but stopping at the shorter one compares only the leading 1 and calls them equal. Absent components are implicitly zero, which also makes 1.0 equal 1.
Edge cases
int() normalizes both to 1 → equal.
Missing chunks read as 0 → equal.