Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[solved] Sort list
#1
Hi

I've been trapped by names I've been getting in a list; I spent some time in looking in internet to find a way; in the current example, I want that list index 1 correspond to 'Name_2' and not 'Name_10' (and so on, in ascending order)

Is there a basic instruction or should I need to split numbers from strings in order to sort?

Thanks for advices

Paul

MyList = ['Name_1', 'Name_10', 'Name_2', 'Name_20', 'Name_3', 'Name_32']
print(f"Initial = {MyList}")
print()
print(f"Test 1 = {sorted(MyList)}")
Reply
#2
You need to use a key. A sorting key is a function that converts each list item into an object more appropriate for sorting.
MyList = ['Name_1', 'Name_10', 'Name_2', 'Name_20', 'Name_3', 'Name_32']

def sort_key(string):
    """Split name_number into [name, number] where number is int"""
    items = string.split('_')
    if len(items) < 2:
        return[items[0], 0]
    return [items[0], int(items[1])]

print(f"Without Key = {sorted(MyList)}")
print(f"With Key = {sorted(MyList, key=sort_key)}")
Output:
Without Key = ['Name_1', 'Name_10', 'Name_2', 'Name_20', 'Name_3', 'Name_32'] With Key = ['Name_1', 'Name_2', 'Name_3', 'Name_10', 'Name_20', 'Name_32']
snippsat likes this post
Reply
#3
You could also just zero pad the numeric parts so they're all the same length, e.g.

>>> l = ["a10", "a02", "a09", "a11", "a23"]
>>> sorted(l)
['a02', 'a09', 'a10', 'a11', 'a23']
Reply
#4
Here an other way.
>>> my_list = ['Name_1', 'Name_10', 'Name_2', 'Name_20', 'Name_3', 'Name_32']
>>> sorted(my_list, key=lambda w: int(w[5:]))
['Name_1', 'Name_2', 'Name_3', 'Name_10', 'Name_20', 'Name_32'] 
The problem is often called Human or Natural sorting,then there is of course made solution for this.
Simple yet flexible natural sorting in Python
>>> from natsort import natsorted
>>> 
>>> my_list = ['Name_1', 'Name_10', 'Name_2', 'Name_20', 'Name_3', 'Name_32']
>>> natsorted(my_list)
['Name_1', 'Name_2', 'Name_3', 'Name_10', 'Name_20', 'Name_32']
Reply
#5
Thanks to all for their support and advices (as well as for internet links)
Reply
#6
MyList = ['Name_1', 'Name_10', 'Name_2', 'Name_20', 'Name_3', 'Name_32']
func = lambda x: int(x[5:])
MyList = sorted([i for i in MyList], key = func)
print(MyList)
Output:
['Name_1', 'Name_2', 'Name_3', 'Name_10', 'Name_20', 'Name_32']
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  list.sort() returning None SmallCoder14 8 403 Mar-19-2024, 09:49 PM
Last Post: SmallCoder14
  [solved] list content check paul18fr 6 614 Jan-04-2024, 11:32 AM
Last Post: deanhystad
  Sort a list of dictionaries by the only dictionary key Calab 1 452 Oct-27-2023, 03:03 PM
Last Post: buran
  Response.json list indices must be integers or slices, not str [SOLVED] AlphaInc 4 6,178 Mar-24-2023, 08:34 AM
Last Post: fullytotal
  Loop through list of ip-addresses [SOLVED] AlphaInc 7 3,835 May-11-2022, 02:23 PM
Last Post: menator01
  [solved] Basic question on list matchiing paul18fr 7 1,807 May-02-2022, 01:03 PM
Last Post: DeaD_EyE
Photo a.sort() == b.sort() all the time 3lnyn0 1 1,277 Apr-19-2022, 06:50 PM
Last Post: Gribouillis
  list sort() function bring backs None CompleteNewb 6 4,000 Mar-26-2022, 03:34 AM
Last Post: Larz60+
  Sort List of Lists by Column Nju 1 10,039 Apr-13-2021, 11:59 PM
Last Post: bowlofred
  How to sort os.walk list? Denial 6 11,288 Oct-10-2020, 05:28 AM
Last Post: Denial

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020