There are two built-in ways to sort in python: the .sort
method or the built-in global sorted
function.
The .sort
method is specific to lists - invoking it on anything other than a list will trigger an attribute error. The sorted
function, however, can accept any iterable as input (lists, strings, dictionaries).
Here’s a high level breakdown of the similarities and differences (I put the differences first):
Attribute | .sort | sorted |
---|---|---|
Sorts any iterable | No - list only | Yes |
In-place | Yes | No |
Return value | None | a new list |
Stable | Yes | Yes |
Default sort order | Ascending | Ascending |
Time complexity | O(n log n) | O(n log n) |
Space complexity | O(n) | O(n) |
Examples
The .sort
method on a simple list:
>>> numbers = [3, 2, 1]
>>> numbers.sort()
>>> numbers
[1, 2, 3]
Try calling .sort
on an iterable other than a list:
>>> letters = 'cba'
>>> letters.sort()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute 'sort'
Woops, not supported.
Calling sorted
on strings and lists:
>>> sorted([3, 2, 1])
[1, 2, 3]
>>> sorted("cba")
['a', 'b', 'c']
sorted
will always return a new list. By the way, dictionaries and sets are also iterables so you can sort them too (you’ll just get back the keys though).
>>> sorted({"c": 1, "b": 2, "a": 3})
['a', 'b', 'c']
>>> sorted({"c", "b", "a"})
['a', 'b', 'c']
Note: dictionaries since python 3.7 preserve the insertion order of keys. By default, calling sorted
on a dictionary, as you see above, sorts by keys.
Sorting with a key function
You need to provide a key function if you’re sorting a list of dictionaries or any object that does not support >
or <
operators.
With .sort
:
>>> objects.sort(key=lambda x: x["x"])
>>> objects
[{'x': 1}, {'x': 2}, {'x': 3}]
With sorted
:
>>> sorted(objects, key=lambda x: x["x"])
[{'x': 1}, {'x': 2}, {'x': 3}]
Sorting in reverse
Elements are sorted in ascending order, smallest value first, by default. Pass reverse=True
to sort by largest value first.
With .sort
:
>>> numbers = [2, 1, 3]
>>> numbers.sort(reverse=True)
>>> numbers
[3, 2, 1]
With sorted
:
>>> numbers = [2, 1, 3]
>>> sorted(numbers, reverse=True)
[3, 2, 1]
In general, I recommend using sorted
unless you absolutely need an in-place sort.