sort by file/directory

Discussion in 'Python' started by Mike Zupan, Sep 10, 2003.

  1. Mike Zupan

    Mike Zupan Guest

    I have a list that includes files and directories

    ie: list = ['file', 'file2', 'dir1','file3','dir2' ]

    I want to sort it so it looks like this

    ['dir1', 'dir2', 'file1','file2','file3' ]


    I'm just wondering if there is an easy way to do this

    Thanks
    Mike
    Mike Zupan, Sep 10, 2003
    #1
    1. Advertising

  2. Mike Zupan

    Peter Hansen Guest

    Mike Zupan wrote:
    >
    > I have a list that includes files and directories
    >
    > ie: list = ['file', 'file2', 'dir1','file3','dir2' ]
    >
    > I want to sort it so it looks like this
    >
    > ['dir1', 'dir2', 'file1','file2','file3' ]
    >
    > I'm just wondering if there is an easy way to do this


    For the above list, executing .sort() would give the correct
    result, but presumably you meant for this to work in a more
    general manner.

    Here's one way to do it, using the Decorate-Sort-Undecorate
    pattern that should be familiar to all Python programmers:

    (Untested code... likely to have various small errors, left
    as an exercise for the reader. :)

    # best to avoid using the name "list" as it conflicts with
    # a name in the built-in module
    names = [ fill in your own data here ]

    import os
    sortme = []
    for name in names:
    # only works if names are absolute, or in current directory
    # you probably have some other way to tell whether
    # something is a folder, but the key thing is to
    # form a tuple with 0 for directories, 1 for files, then
    # the name
    sortme.append((not os.path.isdir(name), name))

    sortme.sort() # in-place sort, of course!

    # remove "decoration" which forced the sort to put directories
    # first, leaving just the names
    names = [item[1] for item in sortme]

    -Peter
    Peter Hansen, Sep 10, 2003
    #2
    1. Advertising

  3. Mike Zupan

    Jeremy Jones Guest

    * Mike Zupan () wrote:
    > I have a list that includes files and directories
    >
    > ie: list = ['file', 'file2', 'dir1','file3','dir2' ]
    >
    > I want to sort it so it looks like this
    >
    > ['dir1', 'dir2', 'file1','file2','file3' ]
    >
    >
    > I'm just wondering if there is an easy way to do this
    >


    Is there anything in the name of the files/directories that specified that
    it is a file or a directory? If not, then I wouldn't think so. When you
    are gathering the file and directory listing (maybe you're using os.walk?),
    then you could at that time do something like (given a 'dir_list' and a
    'file_list'):

    >>> if os.path.isdir(path_to_file):

    .... dir_list.append(os.path.basename(path_to_file))
    .... else:
    .... file_list.append(os.path.basename(path_to_file))

    Then sort the lists and concatenate them together:

    >>> dir_list.sort()
    >>> file_list.sort()
    >>> new_list = dir_list + file_list
    >>> new_list

    ['bin', 'etc', 'sbin', 'tmp', '.muttrc', 'htpasswd', 'httpd.conf',
    'passwd']


    Jeremy Jones
    Jeremy Jones, Sep 10, 2003
    #3
  4. Mike Zupan

    John Hunter Guest

    >>>>> "Mike" == Mike Zupan <> writes:

    Mike> I have a list that includes files and directories ie: list =
    Mike> ['file', 'file2', 'dir1','file3','dir2' ]

    Mike> I want to sort it so it looks like this

    Mike> ['dir1', 'dir2', 'file1','file2','file3' ]


    Mike> I'm just wondering if there is an easy way to do this


    This is a good example of when you should use the decorate, sort,
    undecorate (DSU) pattern. When python sorts tuples, it compares first
    on the first element of the tuple and then on the next element, and
    then so on. If you create tuples where the first element of dirs
    compares less than the first element of files, and the second element
    is just the dir/file name, then you'll get the sort you want. All you
    have have to do is undecorate, ie, remove the unwanted information
    from the tuples. Here is the approach

    import os
    fnames = ('emacs', '.emacs', 'tex','.tcshrc','diary' )

    tmp = [ (not os.path.isdir(fname), fname) for fname in fnames] # decorate
    tmp.sort() # sort
    fnamesSorted = [fname for isdir, fname in tmp] # undecorate

    For more info on DSU, see
    http://groups.google.com/groups?num...e=off&q=dsu group:*python*&btnG=Google Search
    and the Python Cookbook, which has a chapter on sorting mainly devoted
    to DSU.

    Mike> list = ['file', 'file2', 'dir1','file3','dir2' ]

    You may want to avoid the name list because it is a built-in. For
    example, to convert a string to a list of characters, you would do

    seq = list('John Hunter')

    After creating a variable named list, you can no longer do this.


    Cheers,
    John Hunter
    John Hunter, Sep 10, 2003
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. nobody
    Replies:
    0
    Views:
    529
    nobody
    Jun 1, 2004
  2. JerryJ
    Replies:
    11
    Views:
    1,387
    Dave Moore
    Apr 28, 2004
  3. John Black
    Replies:
    6
    Views:
    2,047
    John Harrison
    May 28, 2004
  4. Angus Comber
    Replies:
    7
    Views:
    1,145
    Richard Heathfield
    Feb 5, 2004
  5. Navin
    Replies:
    1
    Views:
    673
    Ken Schaefer
    Sep 9, 2003
Loading...

Share This Page