Home > other >  Sort a list that contains both strings and integers (Python)
Sort a list that contains both strings and integers (Python)

Time:12-06

I want to sort a list of tuples which contain (string, integer, integer). The first value of these tuples can be any string (for example '$', or a numeric string such as '9'). The goal is to sort according to the first element of these tuples, if the comparison occurs between two identical strings I sort according to the second element. I tried the following approach but it turned out to be unsuccessful. Solutions?

array = [('$', 0, 0), ('3', 3, 3), ('7', 5, 6), ('15', 6, 9), ('5', 7, 11), ('17', 8, 13), ('18', 9, 16), ('19', 10, 18), ('16', 11, 20)]
sorted_array = sorted(array, key=lambda x:(x[0], int(x[1])))
print(sorted_array)

Output:

[('$', 0, 0), ('3', 3, 3), ('7', 5, 6), ('15', 6, 9), ('5', 7, 11), ('17', 8, 13), ('18', 9, 16), ('19', 10, 18), ('16', 11, 20)]

I want to get:

[('$', 0, 0), ('3', 3, 3), ('5', 7, 11), ('7', 5, 6), ('15', 6, 9), ('16', 11, 20), ('17', 8, 13), ('18', 9, 16), ('19', 10, 18)]

CodePudding user response:

Using natsort (natural sorting) and str.isdigit you can sort numbers naturally while keeping non numbers first. But the more general rule you might expect is unclear.

from natsort import natsorted 

array = [('$', 0, 0), ('3', 3, 3), ('7', 5, 6), ('15', 6, 9), ('5', 7, 11), ('17', 8, 13), ('18', 9, 16), ('19', 10, 18), ('16', 11, 20)]
sorted_array = natsorted(array, key=lambda x:(x[0].isdigit(), x))
print(sorted_array)

Output:

[('$', 0, 0), ('3', 3, 3), ('5', 7, 11), ('7', 5, 6), ('15', 6, 9), ('16', 11, 20), ('17', 8, 13), ('18', 9, 16), ('19', 10, 18)]

CodePudding user response:

You can get that result with a regular sort if you right justify the string component in the sort key.

array = [('$', 0, 0), ('3', 3, 3), ('7', 5, 6), ('15', 6, 9), 
         ('5', 7, 11), ('17', 8, 13), ('18', 9, 16), ('19', 10, 18), 
         ('16', 11, 20)]

sorted_array = sorted(array,key=lambda x:(x[0].rjust(15),x[1:]))

print(sorted_array)
[('$', 0, 0), ('3', 3, 3), ('5', 7, 11), ('7', 5, 6), ('15', 6, 9), 
 ('16', 11, 20), ('17', 8, 13), ('18', 9, 16), ('19', 10, 18)]
  • Related