Sorting strings containing numbers in a user friendly way
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.
Introduction
Users expect file2.txt to appear before file10.txt, but default string sorting usually does the opposite. That is because ordinary lexicographic sorting compares characters one by one instead of treating embedded digit runs as actual numbers.
Lexicographic Sort vs Natural Sort
A normal string sort compares text like this:
- '
file1' - '
file10' - '
file2'
That result is technically correct for character-by-character comparison, because '1' comes before '2'. A user-friendly sort, often called natural sort, splits each string into text parts and numeric parts so 10 is compared as the number ten rather than the characters '1' and '0'.
A Simple Python Key Function
One common approach is to split each string into alternating text and digit chunks, convert digit chunks to integers, and use the resulting list as the sort key.
Output:
The important detail is that the key contains integers for numeric chunks and lowercase text for alphabetic chunks.
Why casefold() Helps
Natural sorting is often expected to be case-insensitive as well. Using casefold() instead of lower() is a stronger normalization choice for Unicode text.
That produces a more user-friendly order than a raw case-sensitive comparison.
Handling More Complex Names
Real filenames and labels often include multiple numeric segments.
Because the key breaks each string into alternating chunks, it naturally compares chapter2 before chapter10 and then compares section numbers within matching prefixes.
Libraries vs Custom Code
If natural sorting is a core feature in your application, a dedicated library can save time. In Python, the natsort package handles many edge cases around signs, decimals, and locale-aware behavior. A custom regex-based key is still a solid choice when you only need the common integer-in-string case and want a dependency-free solution.
The tradeoff is control versus completeness. Your own key function is easy to inspect. A mature library usually handles more corner cases.
Decide What “User Friendly” Means
Natural sorting is not one universal rule. Different products want different behavior:
- case-sensitive or case-insensitive ordering
- integers only or decimals too
- locale-aware text comparison or binary comparison
- treatment of leading zeros such as
item02
That is why a custom key often becomes the right answer. You define the behavior your users actually expect instead of assuming one canned rule fits every list.
Common Pitfalls
- Using plain string sorting and expecting embedded numbers to behave numerically is the root problem.
- Forgetting case normalization can make otherwise natural results feel inconsistent.
- Converting every digit sequence blindly may not be right if the numbers are version segments, identifiers, or codes with leading-zero semantics.
- Assuming one regex handles decimals, negatives, and localized numbers can lead to subtle bugs.
- Reimplementing a full-featured natural sort from scratch is unnecessary if a well-tested library already matches the requirement.
Summary
- Default string sorting is lexicographic, not numeric-aware.
- Natural sorting works by splitting strings into text and numeric parts.
- A regex-based key function is a clean solution for many common cases.
- '
casefold()improves user-friendly ordering for mixed-case text.' - Define the exact behavior you want, because natural sorting requirements vary by product.
Related reading
- Sorting strings so that hamming distance is low between adjacent strings
- Sorting with stochastic comparisions
- Sorting zipped locked containers in C using boost or the STL
- Source code for Xiaolin Wu's line algorithm in C?
- Space-efficient algorithm for finding the largest balanced subarray?
- Space complexity of distributed algorithm
- space complexity of merge sort using array
- space optimized solution for coin change

DSA Fundamentals
Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.