From: Chris Rebert on
On Thu, Apr 8, 2010 at 4:01 PM, Joaquin Abian <gatoygata2(a)gmail.com> wrote:
> On Apr 9, 12:52 am, Ben Racine <i3enha...(a)gmail.com> wrote:
>> I have a list...
>>
>> ['dir_0_error.dat', 'dir_120_error.dat', 'dir_30_error.dat', 'dir_330_error.dat']
>>
>> I want to sort it based upon the numerical value only.
>>
>> Does someone have an elegant solution to this?
>
> not sure about elegance, but my two cents:
>
>>> mylist = ['dir_0_error.dat', 'dir_120_error.dat', 'dir_30_error.dat', 'dir_330_error.dat']
>>> mylist = [(int(item.split('_')[1]), item) for item in mylist]
>>> mylist.sort()
>>> mylist = [item for idx, item in mylist]
>>> mylist
>
> ['dir_0_error.dat', 'dir_30_error.dat', 'dir_120_error.dat',
> 'dir_330_error.dat']

At least conceptually, that's how list.sort() with a key= argument
works internally (i.e. via Schwartzian transform).

Cheers,
Chris
--
http://blog.rebertia.com
From: Joaquin Abian on
On Apr 9, 1:58 am, Chris Rebert <c...(a)rebertia.com> wrote:
> On Thu, Apr 8, 2010 at 4:01 PM, Joaquin Abian <gatoyga...(a)gmail.com> wrote:
> > On Apr 9, 12:52 am, Ben Racine <i3enha...(a)gmail.com> wrote:
> >> I have a list...
>
> >> ['dir_0_error.dat', 'dir_120_error.dat', 'dir_30_error.dat', 'dir_330_error.dat']
>
> >> I want to sort it based upon the numerical value only.
>
> >> Does someone have an elegant solution to this?
>
> > not sure about elegance, but my two cents:
>
> >>> mylist = ['dir_0_error.dat', 'dir_120_error.dat', 'dir_30_error.dat', 'dir_330_error.dat']
> >>> mylist = [(int(item.split('_')[1]), item) for item in mylist]
> >>> mylist.sort()
> >>> mylist = [item for idx, item in mylist]
> >>> mylist
>
> > ['dir_0_error.dat', 'dir_30_error.dat', 'dir_120_error.dat',
> > 'dir_330_error.dat']
>
> At least conceptually, that's how list.sort() with a key= argument
> works internally (i.e. via Schwartzian transform).
>
> Cheers,
> Chris
> --http://blog.rebertia.com

Chris, thanks for the comment. I did not know that name (Schwartzian
transform)
I knew it as the decorate-sort-undecorate strategy.
Now after learning that it was a Perl idiom I feel somewhat
embarrassed ;-)

BTW, I actually prefer the l.sort(key=f) method.
Just my lazy neurons were back to Python 2.3 when I wrote the
response.

Joaquin

From: Tobiah on

> How about a one liner?
>
> L.sort(key=lambda s: int(s.split('_')[1]))
>
> (Which is not necessarily elegant, but it is short.)

I grant it a measure of elegance as well.

From: Kent =?utf-8?Q?Engstr=C3=B6m?= on
Ben Racine <i3enhamin(a)gmail.com> writes:
> I have a list...
>
> ['dir_0_error.dat', 'dir_120_error.dat', 'dir_30_error.dat', 'dir_330_error.dat']
>
> I want to sort it based upon the numerical value only.
>
> Does someone have an elegant solution to this?

I use code like the hack below to sort miscellaneous strings that
consist of mixed numerical and non-numerical parts.

import re

nsk_re = re.compile("([0-9]+)|([^0-9]+)")
def numeric_sort_key(x):
return [handle_int_nonint(i_ni) for i_ni in nsk_re.findall(x)]

def handle_int_nonint(int_nonint_tuple):
if int_nonint_tuple[0]:
return int(int_nonint_tuple[0])
else:
return int_nonint_tuple[1]

def numerically_sorted(l):
return sorted(l, key=numeric_sort_key)

From: alex23 on
On Apr 9, 8:52 am, Ben Racine <i3enha...(a)gmail.com> wrote:
> I have a list...
> ['dir_0_error.dat', 'dir_120_error.dat', 'dir_30_error.dat', 'dir_330_error.dat']
> I want to sort it based upon the numerical value only.
> Does someone have an elegant solution to this?

This approach doesn't rely on knowing the format of the string:

>>> from string import maketrans, letters, punctuation
>>> a = ['dir_0_error.dat', 'dir_120_error.dat', 'dir_30_error.dat', 'dir_330_error.dat']
>>> def only_numbers(s):
.... nums = s.translate(None, letters+punctuation)
.... return int(nums)
....
>>> a.sort(key=only_numbers)
>>> a
['dir_0_error.dat', 'dir_30_error.dat', 'dir_120_error.dat',
'dir_330_error.dat']

If you're using Python 3.x, the string module has been removed, so you
can find the maketrans function on str there.