I wrote this after reading The Alphanum Algorithm (http://www.davekoelle.com/alphanum.html) by David Koelle a few years ago; my goal was to improve the performances of the Python version of his scripts.
My version is approximatly 10 times faster than it's alphanum.py and about 3 times faster than the alphanum.py_v2.4 on my computer, yielding the same results (for non-unicode at least).
Note: see the version of wizkid in the comments which is even faster.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | def keynat(string):
        '''A natural sort helper function for sort() and sorted()
        without using regular expression.
        '''
        r = []
        for c in string:
                if c.isdigit():
                        if r and isinstance(r[-1], int):
                                r[-1] = r[-1] * 10 + int(c)
                        else:
                                r.append(int(c))
                else:
                        r.append(c)
        return r
 | 
Usage:
>>> items = ['Z', 'a', '10', '1', '9']
>>> sorted(items)
['1', '10', '9', 'Z', 'a']
>>> sorted(items, key=keynat)
['1', '9', '10', 'Z', 'a']
>>> items.sort(cmp=lambda a,b:cmp(keynat(a), keynat(b)))
>>> items
['1', '9', '10', 'Z', 'a']

 Download
Download Copy to clipboard
Copy to clipboard
Where is "keynat2"?
Damn, i should try to check what i'm posting sometimes :) thanks for reporting the typo.
I made my own version before I found this post. So I benchmarked both.
On small keys mine was 30% faster:
And on larger keys it was about 50% faster
My function looks like this. And I think one reason is that I don't call int() on every digit:
Hi wizkid, yes, your version made mine totally obsolete; is 44 to 60% faster than mine on my setup. Thank's for sharing it!