Charlotte Lawton
Charlotte Lawton

Reputation: 11

I am trying to order a string array

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

Answers (3)

Kapocsi
Kapocsi

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

drmrgd
drmrgd

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

whackamadoodle3000
whackamadoodle3000

Reputation: 6748

You could sort with a key:

listy.sort(key=lambda x: int(x[0].split('.')[0].split('_')[1]))

Upvotes: 2

Related Questions