简体   繁体   中英

What is the best way to sort this list?

I have the following list:

my_list = ['name.13','name.1', 'name.2','name.4', 'name.32']

And I would like sort the list and print it out in order, like this

name.1
name.2
name.4
name.13
name.32

What I have tried so far is:

print sorted(my_list)

name.1
name.13
name.2
name.32
name.4

The sorted() command obviously treats the string alphabetically. Maybe it would be better to sort numerically after detecting the . first?

Is there an good way to sort it properly? What would be the most efficient approach to take? How would I apply this is I had a list of tuples and wanted to sort it using the second elemnt of the tuples? For instance:

tuple_list = [('i','name.2'),('t','name.13'),('s','name.32'),('l','name.1'),('s','name.4')]

print tuple_list
'l','name.1'
'i','name.2'
's','name.4'
't','name.13'
's','name.32'

Thanks for your help and, as always, comment if you think the question can be improved/clarified.

Alex

You could try it similarly to this answer:

>>> my_list = ['name.13','name.1', 'name.2','name.4', 'name.32']
>>> sorted(my_list, key=lambda a: (int(a.split('.')[1])))
['name.1', 'name.2', 'name.4', 'name.13', 'name.32']

Or with tuples:

>>> tuple_list = [('i','name.2'),('t','name.13'),('s','name.32'),('l','name.1'),('s','name.4')]
>>> sorted(tuple_list, key=lambda (a,b): (int(b.split('.')[1])))
[('l', 'name.1'), ('i', 'name.2'), ('s', 'name.4'), ('t', 'name.13'), ('s', 'name.32')]

Edit to explain what this does:

The example passes a lambda function to sorted that splits the strings and then converts the second part to an integer. sorted then uses this integer to sort the list items.

This example completely ignores the strings to the left of the dot when sorting. Please let me know if you also need to sort by the first part.

UPDATED ANSWER

As of natsort version 4.0.0, this works out of the box without having to specify any options:

>>> import natsort
>>> my_list = ['name.13','name.1', 'name.2','name.4', 'name.32']
>>> natsort.natsorted(my_list)
['name.1','name.2', 'name.4','name.13', 'name.32']

OLD ANSWER for natsort < 4.0.0

If you do not object to external packages, try the natsort package (version >= 3.0.0):

>>> import natsort
>>> my_list = ['name.13','name.1', 'name.2','name.4', 'name.32']
>>> natsort.natsorted(my_list, number_type=int)
['name.1','name.2', 'name.4','name.13', 'name.32']

The number_type argument is necessary in this case because natsort by default looks for floats, and the decimal point would make all these numbers be interpreted as floats.


Full disclosure: I am the natsort author.

Try this:

sorted(my_list, key=lambda x: int(x.split('.')[1]))

Demo:

>>> my_list = ['name.13','name.1', 'name.2','name.4', 'name.32']
>>> sorted(my_list, key=lambda x: int(x.split('.')[1]))
['name.1', 'name.2', 'name.4', 'name.13', 'name.32']
>>> 

Extending it to the tuple,

sorted(tuple_list, key = lambda x: int(x[1].split('.')[1]))

DEMO:

>>> sorted(tuple_list, key = lambda x: int(x[1].split('.')[1]))
[('l', 'name.1'), ('i', 'name.2'), ('s', 'name.4'), ('t', 'name.13'), ('s', 'name.32')]

This one uses more memory but does not split each item multiple times:

from operator import itemgetter
my_list = ['name.13','name.1', 'name.2','name.4', 'name.32']
my_nlist= [ (int(n.split('.')[1]), i) for i,n in enumerate(my_list)]
my_list = [ my_list[t[1]] for t in sorted(my_nlist, key=itemgetter(0))]

to deal with tuples:

my_list = [('i','name.2'),('t','name.13'),
           ('s','name.32'),('l','name.1'),('s','name.4')]
my_nlist= [ (int(n[1].split('.')[1]), i) for i,n in enumerate(my_list)]
my_list = [ my_list[t[1]] for t in sorted(my_nlist, key=itemgetter(0))]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM