0

I have a very odd problem with the Python list.sort() function.

In my program I get a list of files via os.listdir(). This will return something like

['0.jpg', '1.jpg', '10.jpg', '11.jpg', '12.jpg', '13.jpg', '14.jpg', '15.jpg', '16.jpg', '17.jpg', '18.jpg', '19.jpg', '2.jpg', '20.jpg'] 

(The problem with this list is, that the second to last element should be at the third position and 3.jpg - 9.jpg are somewhere at the end of the list.) Now I want to get the last element in this list (the one with the highest number) so i do a list.sort().

Strangely this doesn´t do anything to the list. I also tried sorted(list) which also returns the exact same list. So I opened up the interpreter and told it to sort the list ["3.jpg","2.jpg","5.jpg"], which for some reason did work.

So my question is: Can anybody please tell my why python doesn´t sort the first list, but the second one is fine? Also, how would I solve this problem, is there some workaround?

In case anyone´s interested: here´s my code:

li=os.listdir("screenshots")
li.sort()
print(li)
Mazdak
  • 105,000
  • 18
  • 159
  • 188

2 Answers2

4

Python sorts strings in lexical ordering. "10" comes before "2" because 1 < 2.

In order to change how it sorts the list, you can use the key= parameter. Assuming the file names are just numbers, you can use

li.sort(key=lambda x: int(x.split(".")[0]))

This separates out the filename and converts it into a number, then uses that number as the key for sorting.

1

What you want is natural sort. You can do natural sorting in python using this code (from here):

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)
Community
  • 1
  • 1
malbarbo
  • 10,717
  • 1
  • 42
  • 57