sorted() vs .sort() in Python
sorted() returns a new sorted list and works on any iterable, while list.sort() sorts a list in place and returns None. Use sorted() by default; use .sort() only when you own the list and want to avoid a copy.
What Is the Difference Between sorted() and .sort()?
.sort() mutates the original list and hands back nothing, which is the classic trap: assigning its result gives you None. sorted() leaves the input untouched and accepts tuples, dicts, sets, and generators too.
nums = [3, 1, 2]
result = sorted(nums) # [1, 2, 3], nums unchanged
nums.sort() # nums is now [1, 2, 3]
bad = nums.sort() # bad is None โ common bug!
sorted({"b": 2, "a": 1}) # ['a', 'b'] โ sorts dict keys
sorted((3, 1, 2)) # [1, 2, 3] โ tuple in, list out
How Does the key Parameter Work?
key= takes a function that is called once per element, and elements are ordered by what it returns. Lambdas handle one-off logic; operator.itemgetter and attrgetter are cleaner and faster for field access.
from operator import itemgetter
words = ["banana", "Fig", "apple"]
sorted(words, key=str.lower) # ['apple', 'banana', 'Fig']
rows = [("bob", 82), ("alice", 91), ("cara", 78)]
sorted(rows, key=lambda r: r[1]) # sort by score
sorted(rows, key=itemgetter(1)) # same, idiomatic
New to the lambda syntax? See lambda functions in Python.
What Does reverse=True Do?
reverse=True flips the order to descending โ both functions accept it, and it keeps the sort stable, unlike negating values or reversing afterward in some edge cases.
sorted([3, 1, 2], reverse=True) # [3, 2, 1]
sorted(rows, key=itemgetter(1), reverse=True)
# [('alice', 91), ('bob', 82), ('cara', 78)]
How Do You Sort by Multiple Keys?
Two ways: return a tuple from key= for same-direction sorts, or exploit the fact that Python's sort is stable (ties keep their previous order) and sort in passes from least to most significant key.
staff = [("sales", "bob", 50), ("eng", "amy", 70), ("sales", "amy", 60)]
# Tuple key โ dept ascending, then salary ascending:
sorted(staff, key=lambda s: (s[0], s[2]))
# Mixed directions โ salary DESC within dept ASC:
staff.sort(key=itemgetter(2), reverse=True) # secondary key first
staff.sort(key=itemgetter(0)) # primary key last
# [('eng', 'amy', 70), ('sales', 'amy', 60), ('sales', 'bob', 50)]
The multi-pass trick works precisely because stability guarantees the salary ordering survives the department sort.
Common Pitfalls
x = nums.sort()sets x to None. Eithernums.sort()on its own line orx = sorted(nums).- Mixed types raise TypeError:
sorted([1, "2"])fails in Python 3. Normalize withkey=stror clean the data. - Strings sort by code point: uppercase sorts before lowercase ("Z" < "a"). Use
key=str.lowerfor human ordering. - Numeric strings sort lexically:
sorted(["10", "9"])puts "10" first. Usekey=int.
Pro Tip: To sort a dict by value, combine sorted with items(): dict(sorted(d.items(), key=itemgetter(1), reverse=True)) โ since Python 3.7 the rebuilt dict keeps that insertion order.