I have some files that need to be sorted by name, unfortunately I can't use a regular sort, because I also want to sort the numbers in the string, so I did some research and found that what I am looking for is called natural sorting.
I tried the solution given here and it worked perfectly.
However, for strings like PresserInc-1_10.jpg
and PresserInc-1_11.jpg
which causes that specific natural key algorithm to fail, because it only matches the first integer which in this case would be 1
and 1
, and so it throws off the sorting. So what I think might help is to match all numbers in the string and group them together, so if I have PresserInc-1_11.jpg
the algorithm should give me 111
back, so my question is, is this possible ?
Here's a list of filenames:
files = ['PresserInc-1.jpg', 'PresserInc-1_10.jpg', 'PresserInc-1_11.jpg', 'PresserInc-10.jpg', 'PresserInc-2.jpg', 'PresserInc-3.jpg', 'PresserInc-4.jpg', 'PresserInc-5.jpg', 'PresserInc-6.jpg', 'PresserInc-11.jpg']
Natural ordering is the default ordering of objects of a specific type when they are sorted in an array or a collection. The Java language provides the Comparable interface that allows us define the natural ordering of a class.
Quite an old question, but very simply put, the Natural Order is an ascending order of the enumerable collection of the comparable elements: For the numbers: 1, 2, 3...
Similarly, for String objects, the default natural ordering is alphabetically sorting. The String class implements the Comparable interface; as a result, the sorting works as we expect. Otherwise, it would have thrown ClassCastException.
On the concept of natural ordering: If the objects of a type have a really-really obvious way to be sorted, than it is the natural ordering. For example, the natural ordering of Strings is the alphabetical order, and the natural order of numbers is ascending order, because it is the first choice anybody would think of.
Google: Python natural sorting.
Result 1: The page you linked to.
But don't stop there!
Result 2: Jeff Atwood's blog that explains how to do it properly.
Result 3: An answer I posted based on Jeff Atwood's blog.
Here's the code from that answer:
import re
def natural_sort(l):
convert = lambda text: int(text) if text.isdigit() else text.lower()
alphanum_key = lambda key: [convert(c) for c in re.split('([0-9]+)', key)]
return sorted(l, key=alphanum_key)
Results for your data:
PresserInc-1.jpg PresserInc-1_10.jpg PresserInc-1_11.jpg PresserInc-2.jpg PresserInc-3.jpg etc...
See it working online: ideone
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With