[Tutor] Sorting a List
Peter Otten
__peter__ at web.de
Thu Jan 13 08:55:13 CET 2011
Bill Campbell wrote:
> On Wed, Jan 12, 2011, Corey Richardson wrote:
>>Hello Tutors,
>>
>>I am generating XML definitions for animations to be used in a
>>FIFE-based game. I need to sort the frames of the animations, and I am
>>currently using:
>>sorted([image for image in os.listdir(path) if image.endswith('.png')])
>>
>>The final output in the XML is:
>>
>><frame source="walk_0.png"/>
>><frame source="walk_1.png"/>
>><frame source="walk_10.png"/>
>><frame source="walk_11.png"/>
>><frame source="walk_2.png"/>
>><frame source="walk_3.png"/>
>><frame source="walk_4.png"/>
>><frame source="walk_5.png"/>
>><frame source="walk_6.png"/>
>><frame source="walk_7.png"/>
>><frame source="walk_8.png"/>
>><frame source="walk_9.png"/>
>>
>>Having frame 10 and 11 between frame 1 and 2 is not desired behavior;
>>how can I sort all of these with walk_10.png and company (this isn't the
>>only animation like this) being after walk_9.png? A google search
>>doesn't return anything I could use. I tried just using
>>[image for image in os.listdir(path) if image.endswith('.png')],
>>but that doesn't appear to have any order.
>
> This is discussed in the Python Cookbook from O'Reilly. If I
> remember correctly, it deals exactly with the problem of sorting
> file names containing numbers as you have above.
>
> Here's a bit of code I use in a module I wrote for dealing with
> RPM versions.
>
> import re
> _digits = re.compile(r'(\d+)')
>
> def ver(s):
> r = _digits.split(s)
> r[1::2] = map(lambda x: int(x), r[1::2])
> return(tuple(r))
Instead of map(lambda x: int(x), ...)
just use map(int, ...)
> class FileInfo(object):
> def __init__(self, fname)
> self.fname = fname
> self.cmp = ver(fname)
>
> def __cmp__(self, othr):
> return cmp(self.cmp, othr.cmp)
You don't need the FileInfo object, you can make ver() the key argument to
list.sort() or sorted():
sorted(filenames, key=ver)
Peter
More information about the Tutor
mailing list