Este
Este

Reputation: 3

How do I sort a list by specific characters within each element?

I have been asked to define a function that sorts a list based on file extension..

I understand sorting, but I don't understand how to start the sort from the "." character.

I want the following result:

>>> extsort(['a.c', 'a.py', 'b.py', 'bar.txt', 'foo.txt', 'x.c'])
['a.c', 'x.c', 'a.py', 'b.py', 'bar.txt', 'foo.txt']

Upvotes: 0

Views: 1213

Answers (2)

niemmi
niemmi

Reputation: 17263

You can pass key function as a parameter for sorted:

>>> l = ['a.c', 'a.py', 'b.py', 'bar.txt', 'foo.txt', 'x.c']
>>> sorted(l, key=lambda x: splitext('.')[1])
['a.c', 'a.py', 'b.py', 'bar.txt', 'foo.txt', 'x.c']

If you need the files to with same extension to be sorted by their name you can change key function to reverse the split result:

>>> l = ['x.c', 'a.py', 'b.py', 'bar.txt', 'foo.txt', 'a.c']
>>> sorted(l, key=lambda x: splitext(x)[::-1])
['a.c', 'x.c', 'a.py', 'b.py', 'bar.txt', 'foo.txt']

Upvotes: 4

ShadowRanger
ShadowRanger

Reputation: 155363

For a solution that works even if some of the files don't have extensions (and is somewhat more self-documenting), use os.path.splitext as part of sorted's key function. When there is no file extension, it will treat the extension as the empty string, '', sorting it before all other extensions:

>>> l = ['b.py', 'a.c', 'a.py', 'bar.txt', 'foo.txt', 'x.c', 'foo']
>>> sorted(l, key=lambda x: os.path.splitext(x)[1])
['foo', 'a.c', 'x.c', 'b.py', 'a.py', 'bar.txt', 'foo.txt']

Note that b.py sorted before a.py here, because it appeared first in the input, and the sort only keyed on the file extension. To make it sort by extension, then full name, key on a tuple of the extension followed by the non-extension name (easily done by slicing os.path.splitext's return value using [::-1] which reverses the order of the elements returned), so a.py precedes b.py regardless of where they appeared in the input:

>>> sorted(l, key=lambda x: os.path.splitext(x)[::-1])
['foo', 'a.c', 'x.c', 'a.py', 'b.py', 'bar.txt', 'foo.txt']

Upvotes: 3

Related Questions