# Can a list be sorted in reverse order?

This seems to be a very useful information. It should be presented during the list lessons.

2 Likes

Thanks for your sharing!!! Itâs really helpful to understand the key in sort.()

Would you please explain why would it sort the list by age then by name after we applied lambda x: (x[1], x[0])?
I tried to understand what does that lambda expression do to the list before sorting the list, so I performed it and it simply just reversed the order of items in each tuple. So it is easy to understand that the list would be sorted by age since the age is moved before name, but my question is how does the computer know to sort it also by age?

lst = [('John', 24), ('Sam', 45), ('Vicky', 23), ('Phil', 45)]
new_lst = list(map(lambda x: (x[1],x[0]), lst))
print(new_lst)
# Out: [(24, 'John'), (45, 'Sam'), (23, 'Vicky'), (45, 'Phil')]

If you pass a callable to the key like the lambda function then it uses the output of this key to sort the data. Effectively you calculate a value for each item in the object youâre sorting (in this case a list) using the key you pass.

Examples of keys would be functions but other callables, e.g. int(), str.lower() and such can be used. Restrictions to this are like normal type comparisons e.g. you canât sort a mix of int and string so choose a key which allows comparisons.

Consider the following-

lst = ['red', 'Balloon', 'Xylophone', 'cat']
print(sorted(lst))
Out: ['Balloon', 'Xylophone', 'cat', 'red']

We sorted the list but capital letters come before lowercase, this is the norm in most character encoding systems. Using a key we can control what we sort by; str.lower for example would effectively create a lowercase version of each string and we sort by the output of this key instead.

print(sorted(lst, key=str.lower))
Out: ['Balloon', 'cat', 'red', 'Xylophone']

The key wonât alter the list itself, itâs all calculated in the background such that using the in-place list .sort method e.g. lst.sort(key=str.lower) only sorts by the key, the capital letters in the string are unaffected.

lst.sort(key=str.lower)
Out: ['Balloon', 'cat', 'red', 'Xylophone']

If youâre unfamiliar with lambda functions then turning them into normal functions can help. Theyâre fairly straightforward once you understand functions and whilst theyâre not used as often as they used to be in Python theyâre probably still worth knowing. Converting it to a normal function might be helpful-

func = lambda x: (x[1], x[0])
def func(x): return (x[1], x[0])

Ideally youâd avoid assigning lambda functions and creating normal functions on a single line but the comparison is easier this way.

So, back to your actual question about sorting with tuples. In your post you have seen the results of the calculations lambda x: (x[1], x[0]) will perform on the contents of lst in order to sort, a series of (age, name) tuples. It will sort by the first element of the tuple first, age, and only when two tuples have identical first elements does it sort by the second tuple element name and so on.

The sorting HOW-TO from the docs has some helpful guidance on sorting in general-
https://docs.python.org/3/howto/sorting.html#sortinghowto

1 Like

Thanks tgrtim!!! The way you explain it is much easier to understand!

1 Like

yup, i told you at the other lesson.

list.append will add anything at the end. such as the example below:
my_list.append(soccer)
would output:
soccer
âŚand len() you can print how many items are in the list:
len(hights)
would output:
6

I have some questions that I donât understand.
I have this two-dimensional list
pizza_and_price=[[âpepperoniâ, 2], [âpineappleâ, 6], [âcheeseâ, 1], [âsausageâ, 3], [âolivesâ, 2], [âanchoviesâ, 7], [âmushroomsâ, 2]]

I want to sort in the order of increasing price and I do this thing
pizza_and_prices.sort(key=lambda pizza_and_prices: pizza_and_prices[1])

And it works. I understand what it means lambda and I read that what I write how the function is equal to write

def f(pizza_and_prices):
return pizza_and_prices[1]

Is it correct ??

I donât understand how lambda pizza_and_prices: pizza_and_prices[1] allow sorting the list in the way of price.
Because if I recall the f(pizza_and_prices) in this way

pizza=f(pizza_and_prices)

and I print the result I see this

[âpineappleâ, 6]

The key argument of the .sort() method is a lambda that returns the position in each pair to use as the sort parameter. We saw in an earlier post,

def f(x):
return x[1]

So we are sorting by price.

pizza_and_price.sort(key=f)
print (pizza_and_price)
[['cheese', 1], ['pepperoni', 2], ['olives', 2], ['mushrooms', 2], ['sausage', 3], ['pineapple', 6], ['anchovies', 7]]

Whatâs more, there is a reverse argument to go along with the keyâŚ

>>> pizza_and_price.sort(key=f, reverse=True)
>>> pizza_and_price
[['anchovies', 7], ['pineapple', 6], ['sausage', 3], ['pepperoni', 2], ['olives', 2], ['mushrooms', 2], ['cheese', 1]]
>>>
1 Like

Hi. Great question, I was wondering how weâd sort a two-dimensional array, with the sub-array containing numerical values. Would the sub-array need to be sorted first?

Iâm sure Iâll stumble upon the answer after some experimentation, and I already have an idea, but this was a great question. I had to point that out.

Regards, Tobes

I think itâs imperative not to be held back by names which may not describe the purpose of the function. It was fine in @patrickd314âs example because he was making it very clear the âlambdaâ keyword was another way of defining an anonymous function, but if we were to define a named function ourselves (a standalone one, that is) I think itâs best to do something along the lines of:

# Note: "arr" is short for array
def sort_two_dimensional_array(arr):  # "sort_name_and_age" may work as well, generally though a function's purpose is to be reusable
return arr[1]
# The rest of the code goes here

In other words, the names we give our functions should provide clarity and perhaps re-usability (optimally, that is). Iâm sure there are many resources out there for properly naming functions and the best practices, but this is something shared among practically all programming languages
Hopefully that helps,
Kind regards,
Tobi

We give it a sorting function, a lambda.

lst.sort(key=lambda x: x[1])

to sort by age in the above example, name_and_age.

A function with positional arguments for list, key, and reverse:

def sort_by(arr, pos, rev):
return sorted(arr, key=lambda x: x[pos], reverse=rev)

names_and_age = [["Sam" , 23], ["Vik", 30], ["Phil", 26], ["John", 18]]
sort_by(names_and_age, 1, 1)
[['Vik', 30], ['Phil', 26], ['Sam', 23], ['John', 18]]
1 Like

The above function is compatible with âdictâ objects, too, as it turns out.

names_and_ages = [{'name': "Sam", 'age': 23}, {'name': "Vik", 'age': 30}, {'name': "Phil", 'age': 26}, {'name': "John", 'age': 18}]
sort_by(names_and_ages, 'age', 1)
[{'name': 'Vik', 'age': 30}, {'name': 'Phil', 'age': 26}, {'name': 'Sam', 'age': 23}, {'name': 'John', 'age': 18}]

Even our simplest functions can turn out to have tremendous horsepower.

FTR

Given this was inspired from/by other content above, it will be noticable that I have wrapped my sequences in a list object. It is well and good that a tuple may be passed to this function since it used sorted(), which generates a new array. Were a tuple to be applied to .sort() then stuff would ensue. We could not depend upon suitable results, if an error is not thrown in the first place.

Lesson here is if you want your objects to be mutable, then donât carelessly hand them off as tuples.

Hello!

I have noticed that âlist.sort(reverse=True)â is used for sorting in reverse order. Why not just use âlist.reverse()â?
Is âlist.reverse()â a new method, which was implemented later than âlist.sort(reverse=True)â, that why it was not used before and presented in the course documentation?

list.reverse() will only reverse the list with order preserved in the opposite direction. list.sort(reverse=True) will reverse and sort.

1 Like

Ooooh! Thank you for the explanation! I guess it can be tricky to understand when reading the documentation, because starting list order was already sorted properly and when using âreverseâ, it was not possible to see this âreverse no-sort catchâ.

1 Like

why do you need the âTrueâ bool in the parenthesis?

Are you referring to the .sort() method? If so, the parentheses are the argument list of the method call.

list.sort()

reverse=True is one of the allowed directive arguments.

2 Likes