So I have a list that looks like this: people_list = [[str name, int numerical value]]
where there are n amounts of lists inside of people_list
. With actual data, it would look like this: people_list = [['jim', 30000], ['james', 30000]]
. I need to sort this list first based on the numerical value in each nested list, so sorted based on people_list[i][1]
where i
is the nth nested list, and the entire people_list needs
to be sorted from highest to lowest numerical value. Then if there are any ties in the numerical value I need to sort the tied lists alphabetically based on the name, so people_list[i][0]
.
I tried the code below to sort, but the output was not exactly how I needed it, and I haven't found any other resources online to get it to sort how I need to.
people_list = [['jim', 33000], ['james', 22000], ['john', 33000], ['zack', 10000]]
sorted_by_int_then_name = sorted(people_list, key=lambda person: (person[1], person[0]), reverse=True)
The output for this code is:
>>> sorted_by_int_then_name
[['john', 33000], ['jim', 33000], ['james', 22000], ['zack', 10000]]
This is sorted correctly numerically, but the names are not sorted alphabetically like I need them to be. I think the issue I'm having might be because I'm using the reverse=True
parameter, but if I don't include that parameter then the list is sorted from lowest numerical value to highest. The output I am looking for would be this:
>>> sorted_by_int_then_name
[['jim', 33000], ['john', 33000], ['james', 22000], ['zack', 10000]]
How can I properly sort by numerical value for people_list[i][1]
and then by people_list[i][0]
whenever the numerical value is tied?
I am running this code using python version 3.8.10 on Ubuntu 20.04.3 LTS
CodePudding user response:
One approach is to multiply the integer by -1
instead of using reverse=True
:
people_array = [['jim', 33000], ['james', 22000], ['john', 33000], ['zack', 10000]]
sorted_by_int_then_name = sorted(people_array, key=lambda person: (-1 * person[1], person[0]))
print(sorted_by_int_then_name)
Output
[['jim', 33000], ['john', 33000], ['james', 22000], ['zack', 10000]]
As an alternative, and taking advantage of the fact that sorted is stable, use a two-pass sort:
from operator import itemgetter
people_array = [['jim', 33000], ['james', 22000], ['john', 33000], ['zack', 10000]]
sorted_by_int_then_name = sorted(people_array, key=itemgetter(0))
sorted_by_int_then_name.sort(key=itemgetter(1), reverse=True)
print(sorted_by_int_then_name)
Output
[['jim', 33000], ['john', 33000], ['james', 22000], ['zack', 10000]]
The two-pass sort can be faster, see this.