Can a list be sorted in reverse order?

Question

Is it possible to sort() a list but do it in reverse order?

Answer

Yes, you can have the sort() function produce a list sorted in reverse order. The default behavior is to sort from least to greatest amount (depending on whether it is a numeric, string or mixed values). The following code example shows that behavior for list1 which contains only numbers.

list1 = [14, 45, 98, 23, 77, 32, 15, 22, 8, 33, 21, 64]
list1.sort()
print(list1)
# [8, 14, 15, 21, 22, 23, 32, 33, 45, 64, 77, 98]

By using the reverse parameter for sort(), you can change the behavior and have the list sorted in the other direction. This code example shows how to use reverse.

ist1 = [14, 45, 98, 23, 77, 32, 15, 22, 8, 33, 21, 64]
list1.sort(reverse=True)
print(list1)
# [98, 77, 64, 45, 33, 32, 23, 22, 21, 15, 14, 8]
28 Likes

How can we short a list based on the sublist element using sort() method?

example:

#below list is composed of names_list and age_list
names_and_age = ["Sam" , 23], ["Vik", 30], ["Phil", 26"], ["John", 18]

sorting names_and_age list based on age (ie., send element in the sublist).

11 Likes

Use the “key” keyword parameter:

names_and_age = [["Sam" , 23], ["Vik", 30], ["Phil", 26], ["John", 18]]
names_and_age.sort(key = lambda x: x[1])
print(names_and_age)

# Output:
[['John', 18], ['Sam', 23], ['Phil', 26], ['Vik', 30]]
37 Likes

this key parameter works quite awesome. what is lambda here? It looks like a predefined function. Would you explain this in detail?:slightly_smiling_face:

3 Likes

The keyword parameter key in an iterable method says something like:

  1. Apply the expression to the right of the = operator sequentially to each item in the given iterable, placing each returned value into a new iterable.
  2. Be sure to keep track of which value in the new iterable is associated with which item in the original one. **
  3. Then perform the method on the new iterable.
  4. Then return the original iterable, ordered by the order of items in the new one.

lambda is a way to write a function on one line. It is in this case equivalent to:

def f(x):
    return x[1]

… then I could write:

names_and_age = [["Sam" , 23], ["Vik", 30], ["Phil", 26], ["John", 18]]
names_and_age.sort(key = f)  # Note that I name only the function, no parameters needed
print(names_and_age)

# Output
[['John', 18], ['Sam', 23], ['Phil', 26], ['Vik', 30]]

** I actually don’t how it is actually accomplished “under the hood”, but for me, it is helpful to think of the “new” iterable looking something like:

[[23, ["Sam" , 23]], [30, ["Vik", 30]], [26, ["Phil", 26]], [18, ["John", 18]]]

So, each new_list item looks like this:
[item_to_sort_on, original_list_or_tuple_or_whatever_item]

so we leverage the fact that sort() by default sorts on item[0] :

new_list.sort()
print([item[1] for item in new_list])

# Gets you to
[['John', 18], ['Sam', 23], ['Phil', 26], ['Vik', 30]]

43 Likes

Wow… Now i get it. You did described well. Thank you so much.

2 Likes

could you explain how the lambda works? because i get the other stuff but not this.

Correct me if I’m wrong, but what i understood is this:

“key” applies the sort function to the list(“x” in this case), and more specifically to the 2nd integer(which is [1]) . right??? Because if i write names_and_age.sort(key = lambda x: x[0]) instead of [1], the sorting will be done based on each names, alphabetically .

in my opinion, it would be more easy for beginner level learners like me to write:
def f(names_and_age): #instead of f(x)#
return names_and_age[1]
names_and_age = [[“Sam” , 23], [“Vik”, 30], [“Phil”, 26], [“John”, 18]]
names_and_age.sort(key = f)
print(names_and_age)

thank you in advance.

6 Likes

I think you’re right about that it’s bad to introduce a new way to define a function at the same time as starting to use functions in a new way.

lambda doesn’t do anything new. makes a function.

Another way that you could get a suitable function to use as key is with operator.itemgetter which corresponds to the [] operator

from operator import itemgetter
itemgetter(3)([1, 2, 3, 4, 5])  # 4
1 Like

You appear to understand it perfectly!

why do we write (key = lambda x: x[1])?

why x: x[1] and not just x[1]?

1 Like

You don’t have an x, that would be a name error.
You’re not looking for the second item of x. What you’re looking to say is “given an x, here’s how to obtain its second value.”
A function is a relation between some input (in this case some x) and some output (in this case the second item of x)
You’re describing that relation, so that sort can sort by the second item of value(s)

6 Likes

thank you for clearing that up!

You showed it in your example:

def f(names_and_age): #instead of f(x)#
    return names_and_age[1]

Well,

lambda x: x[1] Says,

Here is a function whose parameter is x: return x[1]

You would have written

lambda names_and_age: names_and_age[1]

… and it would have been fine.

5 Likes

Is there a difference between the functions which comes before and after the list ? How can I remember it?

Hi there! Would you mind using an example to explain what you mean?

I don’t know. Is there a difference between " list.append" and "len(list) " types?

Thanks so much for teaching about key and lambda!! It is a very useful tool to learn :slight_smile:

1 Like

My output only shown sorted number of ages and the names is not sorted?
Can someone tell me why ?

#printout the order of two variables in sorting zip
names = [‘John’,‘Sam’,‘Vicky’,‘Phil’]
ages = [24, 45, 23, 45]
names_ages= list(zip(names, ages))
print(names_ages)
#sorting names_ages following alphabet order names:
sorted_names_ages = names_ages.sort( key = lambda x:x[1])
print(“Sorted names and ages”+ str(names_ages))

Output:

[(‘John’, 24), (‘Sam’, 45), (‘Vicky’, 23), (‘Phil’, 45)]
Sorted names and ages[(‘Vicky’, 23), (‘John’, 24), (‘Sam’, 45), (‘Phil’, 45)]

1 Like

The difference is :

  • “list.append” will add an item to the end of “list”
  • while len(list) will return the number of item contained in “list”

Hope it helps :slight_smile:

1 Like

In your example there are only two sets of data to sort by, either the names or the ages. You used the key with lambda x: x[1] which is asking it to sort by the second item. Since you used zip you effectively have a sequence of items like so-
(‘John’, 24)
(‘Sam’, 45)
(‘Vicky’, 23)
(‘Phil’, 45)

Note that the second item x[1] is the age. So we sort by x[1] which is age-
(‘Vicky’, 23)
(‘John’, 24)
(‘Sam’, 45)
(‘Phil’, 45)

We didn’t ask to sort by age then name so it doesn’t happen. If you wanted to you can ask for it to sort by item1, then by item0 in a single line-

names_age.sort(key=lambda x: (x[1], x[0]))
# Out: [('Vicky', 23), ('John', 24), ('Phil', 45), ('Sam', 45)]
# Now 'Phil' comes before 'Sam'

Or consider operator.itemgetter-
https://docs.python.org/3/library/operator.html#operator.itemgetter

from operator import itemgetter

names_age.sort(key=itemgetter(1, 0))
2 Likes