Python Forum

Full Version: [solved] Sort list
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
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)}")
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']
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']
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']
Thanks to all for their support and advices (as well as for internet links)
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']