22

I'm populating a tkinter listbox with files from a directory. The names of the files all start with a number from 01 - n. When I view the files in the directory they appear in numerical order. However, when I load the files into a listbox they aren't ordered numerically. I can change the leading numbers around, but the same files will always appear in the same spot.

I'm just using simplified item names to keep things simple with this example. It still shows that they're not being sorted alphabetically nor numerically.

The list should appear as the following in my listbox

01. itemA
02. itemB
03. itemC
04. itemD

But it appears as:

01. itemA
04. itemD
02. itemB
03. itemC

I can change the leading numbers around, but the files will always populate in the same order (by name, not number). The strange thing is, it's not even alphabetical order.

I've used this

i = 0
for filename in os.listdir(directory):
      fileList.insert(i, filename)
      i = i + 1

And this

 for filename in os.listdir(directory):
        fileList.insert(END, filename)

Both result in the same thing.

user1104854
  • 2,137
  • 12
  • 51
  • 74
  • The docs says ["The list is in arbitrary order."](http://docs.python.org/2/library/os.html#os.listdir)! Perhaps it is modification date? did you delve into any other possibilities? – Andy Hayden Oct 29 '12 at 12:53
  • 3
    you could try `for filename in sorted(os.listdir(directory)):` http://docs.python.org/2/library/functions.html#sorted – FabienAndre Oct 29 '12 at 12:54

2 Answers2

28

os.listdir doesn't guarantee any ordering of the contents of a directory. If you want the items to be sorted, just sort them using the builtin sorted function (with an appropriate key function if necessary).

mgilson
  • 300,191
  • 65
  • 633
  • 696
  • 1
    In fact the docs back you up: ["The list is in arbitrary order."](http://docs.python.org/2/library/os.html#os.listdir) (!) – Andy Hayden Oct 29 '12 at 12:56
  • @hayden -- Yeah. There probably is *some* method to the madness, but it is probably filesystem dependent and so it's easier for the docs to just say "arbitrary". Thanks for posting a link though :) – mgilson Oct 29 '12 at 12:57
  • Thanks, worked perfectly. Is there any reason why you would want it in arbitrary order? I can only think of more instances when you'd want it sorted than not. – user1104854 Oct 29 '12 at 12:59
  • 1
    @user1104854 -- Sure. If you want to perform the same operation on all the files, but don't care what order, then you might as well save yourself the `O(nlogn)` sort step and work with the files in the order that the filesystem gives them to you. And, if you *need* them to be sorted, that's a pretty easy thing to do :). – mgilson Oct 29 '12 at 13:01
  • @mgilson So basically for speed? – user1104854 Oct 29 '12 at 13:07
  • 1
    @user1104854 -- Speed is a big part of it. A second question is *how* do you sort them? Sometimes you want them sorted by name, sometimes by file modification time, sometimes by filetype, (I'm sure the list could continue) ... Rather than making `os.listdir` more complicated, they can just push the responsibility of sorting back on the user. – mgilson Oct 29 '12 at 13:10
19

Try this.

for index, filename in enumerate(sorted(os.listdir(directory))):
        print '{0:02d}. {1}'.format(index + 1, filename)

In the event that the number is part of the filename go with @FabienAndre's comment.

for filename in sorted(os.listdir(directory)):
        print filename
John
  • 13,197
  • 7
  • 51
  • 101
  • 1
    It would be `str(index+1).zfill(2)+'. '+filename` -- But (from the looks of it, the 01. is part of the filename ...) – mgilson Oct 29 '12 at 12:58
  • @mgilson, Fixed the formatting, however I don't think it's part of the filename as he has the i variable in the first code snippet. – John Oct 29 '12 at 13:03
  • While you're using `.format`, you might as well put the `' '` and `filename` in there too. `'{0:02d}. {1}'.format(index+1,filename)` – mgilson Oct 29 '12 at 13:03
  • The variable is so that `tkinter` knows where to insert the item in the listbox. – mgilson Oct 29 '12 at 13:04