FAQ
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?

Thanks,
Ben R.

Search Discussions

  • Chris Rebert at Apr 8, 2010 at 10:54 pm

    On Thu, Apr 8, 2010 at 3:52 PM, Ben Racine 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.
    a = ['dir_0_error.dat', 'dir_120_error.dat', 'dir_30_error.dat',
    'dir_330_error.dat']
    def key(item):
    return int(item.split('_')[1])
    a.sort(key=key)

    Cheers,
    Chris
  • Gary Herron at Apr 8, 2010 at 10:59 pm

    Ben Racine 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?

    Thanks,
    Ben R.
    How about a one liner?

    L.sort(key=lambda s: int(s.split('_')[1]))


    (Which is not necessarily elegant, but it is short.)

    Gary Herron
  • Joaquin Abian at Apr 8, 2010 at 11:01 pm

    On Apr 9, 12:52?am, Ben Racine 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?

    Thanks,
    Ben R.
    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']

    joaquin
  • Chris Rebert at Apr 8, 2010 at 11:58 pm

    On Thu, Apr 8, 2010 at 4:01 PM, Joaquin Abian wrote:
    On Apr 9, 12:52?am, Ben Racine 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
  • Joaquin Abian at Apr 9, 2010 at 1:21 pm

    On Apr 9, 1:58?am, Chris Rebert wrote:
    On Thu, Apr 8, 2010 at 4:01 PM, Joaquin Abian wrote:
    On Apr 9, 12:52?am, Ben Racine 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
  • Lie Ryan at Apr 9, 2010 at 12:43 am

    On 04/09/10 08:52, Ben Racine 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?

    Thanks,
    Ben R.
    list.sort() and sorted() accept `key` argument, which receives a
    callable that transform the item to be sorted into sorting key. So if
    you have:

    l = ['dir_30_error.dat', 'dir_120_error.dat',
    'dir_330_error.dat', 'dir_0_error.dat']

    # 'dir_0_error.dat' -> 0
    # 'dir_30_error.dat' -> 30
    def getnum(s):
    return int(''.join(x for x in s if x.isdigit()))

    # sort based on getnum()'s return value
    l.sort(key=getnum)
  • Tobiah at Apr 9, 2010 at 4:19 pm

    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.
  • Kent Engström at Apr 10, 2010 at 11:31 am

    Ben Racine <i3enhamin at 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)
  • Alex23 at Apr 10, 2010 at 2:51 pm

    On Apr 9, 8:52?am, Ben Racine 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.
  • MRAB at Apr 10, 2010 at 3:04 pm

    alex23 wrote:
    On Apr 9, 8:52 am, Ben Racine 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.
    The string module still exists in Python 3.x, but the string functions
    which have been superseded by string methods have been removed.
  • Alex23 at Apr 10, 2010 at 3:20 pm

    MRAB wrote:
    The string module still exists in Python 3.x, but the string functions
    which have been superseded by string methods have been removed.
    Awesome, thanks for the heads up.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
grouppython-list @
categoriespython
postedApr 8, '10 at 10:52p
activeApr 10, '10 at 3:20p
posts12
users9
websitepython.org

People

Translate

site design / logo © 2022 Grokbase