Reputation: 11
I have a 2d list, in the first part I have a string which represents the measurement number while the 2nd part represents the corresponding numerical measurement. I have attached the list below, and python seems to have ordered it 1,10,11,...,2,3,4 etc.
My question is how do I get it in chronological order? So that PI_1.txt is followed by PI_2.txt and not PI_10.txt
['PI_1.txt', 1004.1]
['PI_10.txt', 1104.8]
['PI_11.txt', 1115.3]
['PI_12.txt', 1104.7]
['PI_2.txt', 1019.1]
['PI_3.txt', 1062.3]
['PI_4.txt', 1239.6]
['PI_5.txt', 1143.2]
['PI_6.txt', 1139.3]
['PI_7.txt', 1131.3]
['PI_8.txt', 1130.9]
['PI_9.txt', 1108.9]
The list is above to make my description a bit simpler.
Thank you!
p.s. I can't change the filenames so they are just integers, as part of my code uses a selection based on whether or not "PI" is included in the filename
Upvotes: 1
Views: 49
Reputation: 1032
If you want to sort the list in-place (as opposed to returning a sorted copy of the list) and the files are consistently named, you can use the following code which uses a key function to determine the order.
data = [
['PI_1.txt', 1004.1],
['PI_10.txt', 1104.8],
['PI_11.txt', 1115.3],
['PI_12.txt', 1104.7],
['PI_2.txt', 1019.1],
['PI_3.txt', 1062.3],
['PI_4.txt', 1239.6],
['PI_5.txt', 1143.2],
['PI_6.txt', 1139.3],
['PI_7.txt', 1131.3],
['PI_8.txt', 1130.9],
['PI_9.txt', 1108.9]
]
data.sort(key=lambda d: int(d[0][3:-4]))
This code accesses the first item in the sublist, selects everything between the 3rd and last 4 characters, converts it to an integer, and then uses that value to order the 2-d list.
Upvotes: 2
Reputation: 733
For this kind of task, I like to use the natsort
library to handle naturally sorting the numbers with operator.itemgetter
to help with identifying the element by which the nested list should be sorted. With that all together, you can easily sort your 2D list like this:
#!/usr/bin/env python
from operator import itemgetter
from natsort import natsorted
from pprint import pprint as pp
d = [['PI_1.txt', 1004.1],
['PI_10.txt', 1104.8],
['PI_11.txt', 1115.3],
['PI_12.txt', 1104.7],
['PI_2.txt', 1019.1],
['PI_3.txt', 1062.3],
['PI_4.txt', 1239.6],
['PI_5.txt', 1143.2],
['PI_6.txt', 1139.3],
['PI_7.txt', 1131.3],
['PI_8.txt', 1130.9],
['PI_9.txt', 1108.9]]
print('Before: ')
pp(d)
print('\nAfter: ')
d = natsorted(d, key=itemgetter(0))
pp(d)
The resultant output looks like this:
Before:
[['PI_1.txt', 1004.1],
['PI_10.txt', 1104.8],
['PI_11.txt', 1115.3],
['PI_12.txt', 1104.7],
['PI_2.txt', 1019.1],
['PI_3.txt', 1062.3],
['PI_4.txt', 1239.6],
['PI_5.txt', 1143.2],
['PI_6.txt', 1139.3],
['PI_7.txt', 1131.3],
['PI_8.txt', 1130.9],
['PI_9.txt', 1108.9]]
After:
[['PI_1.txt', 1004.1],
['PI_2.txt', 1019.1],
['PI_3.txt', 1062.3],
['PI_4.txt', 1239.6],
['PI_5.txt', 1143.2],
['PI_6.txt', 1139.3],
['PI_7.txt', 1131.3],
['PI_8.txt', 1130.9],
['PI_9.txt', 1108.9],
['PI_10.txt', 1104.8],
['PI_11.txt', 1115.3],
['PI_12.txt', 1104.7]]
Upvotes: 0
Reputation: 6748
You could sort with a key:
listy.sort(key=lambda x: int(x[0].split('.')[0].split('_')[1]))
Upvotes: 2