Pythonic list reordering

B

Ben Racine

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.
 
J

Joaquin Abian

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
 
C

Chris Rebert

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
 
L

Lie Ryan

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)
 
J

Joaquin Abian

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
 
A

alex23

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)
....['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.
 
M

MRAB

alex23 said:
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)
...['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.
 
A

alex23

MRAB said:
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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top