Posts: 300
Threads: 72
Joined: Apr 2019
Jul-09-2021, 05:21 PM
(This post was last modified: Jul-10-2021, 10:04 AM by paul18fr.)
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)}")
Posts: 6,798
Threads: 20
Joined: Feb 2020
Jul-09-2021, 05:44 PM
(This post was last modified: Jul-09-2021, 05:44 PM by deanhystad.)
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']
Posts: 1,838
Threads: 2
Joined: Apr 2017
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']
Posts: 7,320
Threads: 123
Joined: Sep 2016
Jul-09-2021, 07:34 PM
(This post was last modified: Jul-09-2021, 07:34 PM by snippsat.)
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']
Posts: 300
Threads: 72
Joined: Apr 2019
Thanks to all for their support and advices (as well as for internet links)
Posts: 45
Threads: 0
Joined: Aug 2021
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']
|