Python sort vs sorted: In-Place vs New List
python sort vs sorted: Explains the difference between Python's list.sort() in-place method and the sorted() built-in, covering syntax, memory behavior, iterable suppo...
When you need to order a collection in Python, two standard tools are available: the list.sort() method and the sorted() built-in function. The choice between python sort vs sorted comes down to one fundamental distinction: sort() mutates the original list in place and returns None, while sorted() returns a new list and leaves the original untouched. That single difference drives most of the practical decisions about which to use in real code.
The Core Difference: Mutation vs a New List
The most important behavior to internalize is what each operation does to your data. list.sort() rearranges the elements of the list it is called on and returns None. It never produces a new list object.
numbers = [3, 1, 2] result = numbers.sort() print(result) # None print(numbers) # [1, 2, 3]
The variable result holds None, not the sorted list. The original numbers list has been reordered in place.
The sorted() function, by contrast, copies the elements into a brand-new list, sorts that copy, and returns it. The original iterable is never modified.
numbers = [3, 1, 2] result = sorted(numbers) print(result) # [1, 2, 3] print(numbers) # [3, 1, 2]
Here numbers keeps its original order, and result is an independent sorted list. This distinction is not cosmetic; it determines whether other references to the same list see the new order and whether you need to keep the original sequence.
Syntax and Parameters
Both sort() and sorted() accept the same two keyword arguments: key and reverse. The key argument specifies a callable that extracts a comparison value from each element, and reverse controls descending order.
words = ["banana", "apple", "Cherry"] words.sort(key=str.lower) print(words) # ['apple', 'banana', 'Cherry']
words = ["banana", "apple", "Cherry"] ordered = sorted(words, key=str.lower, reverse=True) print(ordered) # ['Cherry', 'banana', 'apple']
In both cases the key callable is invoked exactly once per element, and the resulting values are used for the comparisons. This matters for performance: an expensive key function is not called repeatedly during the sort; it is called once per item up front.
The parameter names and behavior are identical, so code written for one can usually be switched to the other without changing the key logic. The only syntactic difference is that sort() is a method on a list object, while sorted() is a standalone function that takes the iterable as its first argument.
| Feature | list.sort() | sorted() |
|---|---|---|
| Mutates original | Yes | No |
| Return value | None | New list |
| Input type | List only | Any iterable |
| Memory | In-place, no copy | Allocates a new list |
key parameter | Yes | Yes |
reverse parameter | Yes | Yes |
sorted() Works on Any Iterable
The sort() method exists only on lists. If your data lives in a tuple, a dictionary, a set, a generator, or a string, you cannot call sort() on it directly. The sorted() function accepts any iterable and always returns a list.
data = {"b": 2, "a": 1, "c": 3} sorted_keys = sorted(data) print(sorted_keys) # ['a', 'b', 'c']
Iterating over a dictionary yields its keys, so sorted(data) returns a sorted list of keys. The same pattern works for tuples and sets:
scores = (95, 87, 92, 78) ordered = sorted(scores, reverse=True) print(ordered) # [95, 92, 87, 78]
Note that the result is always a list, even when the input is a tuple or a set. If you need the sorted result back in the original container type, you must convert it yourself, for example with tuple(sorted(scores)).
A generator is also a valid input to sorted(), but be aware that consuming a generator exhausts it. After calling sorted(gen), the generator is spent and cannot be iterated again. If you need to use the original sequence later, materialize it into a list first.
Memory and Mutation Behavior
Because list.sort() reorders elements in place, it does not allocate a second list to hold the sorted output. This makes it the more memory-efficient choice when the original list is large and no longer needed in its original order. The list object itself is reused, and only the references inside it are rearranged.
The sorted() function must build a new list containing the same elements, which means an additional allocation proportional to the size of the input. For a list with millions of items, that extra list represents real memory pressure. The original list remains in memory as well, so peak usage is roughly double the element count until the original is released.
There is also a correctness angle. If multiple variables or data structures reference the same list, calling sort() changes what all of them see. That can be desirable when the sorted order is the canonical state, but it can also introduce subtle bugs when some part of the code still expects the original ordering. Using sorted() keeps the original list intact and gives the caller a separate sorted copy, which is safer when the original order must be preserved for later processing.
Performance Considerations
Neither approach is universally faster, because the dominant cost in most sorts is the comparison work, not the container mechanics. Both sort() and sorted() use the same underlying sorting algorithm, and both invoke the key function once per element. The practical performance difference comes down to allocation and mutation.
list.sort() avoids allocating a new list, so for a large list that is no longer needed in its original order, it uses less memory and avoids the copy step. sorted() pays the cost of building a new list, but it also leaves the original untouched, which can save work elsewhere if the original order is still required.
There is no meaningful speed difference between the two for typical in-memory data. The choice should be driven by whether you need the original list preserved and whether the input is actually a list. If you are sorting a list and do not need the original order, sort() is the leaner option. If you are sorting any other iterable, or you must keep the original sequence, sorted() is the only correct choice.
When to Use Each
Use list.sort() when all of the following hold: the input is a list, the original order is no longer needed, and you want to avoid the memory cost of a second list. This is common in data-processing pipelines where a list is loaded, sorted, and then used exclusively in its sorted form.
Use sorted() when the input is not a list, when the original collection must remain unchanged, or when you need the sorted result as a separate value while continuing to use the original. This is typical when sorting dictionary keys, tuples, or generator output, or when the original list is referenced elsewhere and must keep its order.
The decision is rarely about raw speed. It is about ownership of the data. If the list is yours alone and its unsorted state has no future use, sort() is the simpler and more memory-conscious choice. If the data is shared, read elsewhere, or arrives as a non-list iterable, sorted() gives you a new sorted list without disturbing the source.
Edge Cases and Common Mistakes
The most frequent mistake is assuming that sort() returns the sorted list. Because it returns None, code like result = my_list.sort() leaves result as None, and any later attempt to iterate or index it fails. Always remember that sort() modifies the list in place and returns nothing.
Another subtle point is sort stability. Both sort() and sorted() are stable, meaning that elements with equal keys retain their original relative order. This is important when sorting by multiple criteria in successive passes: sorting by one key and then by another preserves the first ordering among ties in the second. The stability guarantee applies to both approaches, so you can rely on it regardless of which you choose.
Finally, be careful when sorting dictionaries directly. sorted(data) sorts the keys, which is usually what you want, but sorted(data.values()) sorts the values instead. If you need to sort by both key and value, you must extract the items and provide a key function, for example sorted(data.items(), key=lambda item: item[1]). The sorted() function gives you the flexibility to sort any projection of your data, while sort() is limited to the exact elements stored in the list. Choosing between them starts with knowing what your data structure is and whether you can afford to lose its original order.