Q&A
What is the difference between sort() and sorted() in Python?
Overview
Python offers two ways to sort, and confusing them causes a very common bug. The core distinction: sort() mutates a list and gives back nothing; sorted() leaves the input alone and gives back a new list. Choosing correctly depends on whether you need the original preserved and whether your data is even a list.
graph TD
A[Need to sort] --> B{Keep the original?}
B -->|no, mutate in place, it's a list| C["list.sort() → returns None"]
B -->|yes, want a new sorted copy| D["sorted(iterable) → returns new list"]
D --> E[Works on ANY iterable]
style D fill:#1e1b4b,color:#fff
list.sort() - in place, returns None
nums = [3, 1, 2]
result = nums.sort() # sorts nums IN PLACE
print(nums) # [1, 2, 3] - original changed
print(result) # None - sort() returns None!
Because it returns None, the classic mistake is nums = nums.sort() - that overwrites your list with None.
sorted() - new list, original untouched
nums = [3, 1, 2]
ordered = sorted(nums) # returns a NEW sorted list
print(ordered) # [1, 2, 3]
print(nums) # [3, 1, 2] - original unchanged
sorted() works on any iterable and always produces a list:
sorted("dcba") # ['a', 'b', 'c', 'd'] (string → list)
sorted((3, 1, 2)) # [1, 2, 3] (tuple → list)
sorted({3, 1, 2}) # [1, 2, 3] (set → list)
sorted({"b": 2, "a": 1}) # ['a', 'b'] (dict → keys sorted)
Shared Parameters: key and reverse
Both accept the same options:
words = ["banana", "kiwi", "apple"]
sorted(words, key=len) # ['kiwi', 'apple', 'banana'] (by length)
sorted(words, reverse=True) # descending
words.sort(key=str.lower) # case-insensitive, in place
# sort objects by an attribute / dict by a field:
people.sort(key=lambda p: p["age"])
sorted(records, key=lambda r: (r["dept"], -r["salary"])) # multi-key
key takes a function applied to each element to derive the comparison value; reverse=True flips the order.
Comparison Table
| Aspect | list.sort() |
sorted() |
|---|---|---|
| Type | List method | Built-in function |
| Input | Lists only | Any iterable |
| Modifies original? | Yes (in place) | No |
| Returns | None |
A new sorted list |
| Memory | No extra list | Creates a new list |
key / reverse |
Yes | Yes |
| Algorithm | Timsort (stable) | Timsort (stable) |
Stability
Both are stable - elements that compare equal keep their original relative order. This lets you sort by multiple criteria with successive sorts (sort by secondary key first, then primary).
When to Use Which
sort()- you have a list, don't need the original, and want to avoid the memory of a copy.sorted()- you need to keep the original, you're sorting a non-list iterable (tuple, string, dict, generator), or you want to sort inside an expression.
Why This Matters in Interviews
This is a frequent Python question precisely because of the None gotcha. Nail: sort() mutates in place and returns None (so never do x = x.sort()); sorted() returns a new list and works on any iterable; both share key/reverse and are stable Timsort. Demonstrating key with a lambda (and multi-key tuples) and explaining stability shows fluency.
Common Pitfalls
nums = nums.sort()→numsbecomesNone(the #1 mistake).- Calling
.sort()on a non-list (tuples/strings have no.sort()- usesorted()). - Expecting
sorted()to modify the original (it doesn't). - Forgetting that
sorted()of a dict sorts its keys by default. - Passing a comparison value instead of a
keyfunction (Python 3 droppedcmp; usekeyorfunctools.cmp_to_key).
References
- Python
sorted(): https://docs.python.org/3/library/functions.html#sorted - Python Sorting HOW TO: https://docs.python.org/3/howto/sorting.html