简体   繁体   中英

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

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)]

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)]

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)]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM