Sorting and the sort() Method
Lambda functions used as sort keys provide a temporary comparison value for each element without modifying the original list.
A Different Way to Sort
Sorting does not always mean comparing each element in its original form. A lambda function can transform each element into a temporary comparison value, and sort() can use those values to decide the order. The elements themselves remain in their original form while their positions are reordered. List comprehensions solve a related but different problem: they create a new list by transforming and optionally filtering values from an existing list.
What do you think happens?
A list contains two point dictionaries in this order: {'x': 2, 'y': 5}, then {'x': 4, 'y': 1}. What order will result when sort() uses lambda p: p['x'] as its key?
Reveal answer
Answer: The point with x equal to 2 comes first, so the points stay in their original order.
The lambda receives each point and returns its x-coordinate. The comparison values are 2 and 4, and 2 comes before 4 in ascending order.
Tracing a Lambda Sort Key
A lambda is a small, unnamed function written inline. When it is supplied to sort() through the key parameter, sort() gives the lambda each element one at a time. The lambda returns a value, and that returned value becomes the basis for comparison. The original element is still the item that gets moved in the list; the returned key is only the temporary value used to determine ordering.
points = [{'x': 4, 'y': 1}, {'x': 2, 'y': 5}] points.sort(key=lambda p: p['x']) print(points)
Building Lists with Comprehensions
A list comprehension creates a new list from a source list. Its general structure is [expression for item in list if condition]. The expression determines what value is placed in the new list. The for clause takes elements from the source list, and the optional if condition decides which elements are included. Unlike a lambda used as a sort key, a comprehension is specifically a list-building operation.
[4, 6, 8][4, 8]In the filtered example, the condition is checked for each source element. Only 2 and 4 pass the even-number condition, and the expression then transforms them into 4 and 8. The source list is not replaced; the comprehension collects its results in a new list.
Combining Transformation and Ordering
The two tools can be used in sequence. A list comprehension can first create a new collection of selected or transformed values. A lambda can then provide the comparison value needed to sort that collection. The comprehension builds the data; the lambda supplies sorting logic.
Sort Selected Points by Their X-Coordinate
Create a new list containing points whose x-coordinate is at least 2, then sort that new list by x-coordinate.
Start with the source points: The points are [{'x': 3, 'y': 1}, {'x': 1, 'y': 4}, {'x': 2, 'y': 2}].
Filter with a comprehension: The condition p['x'] >= 2 keeps the points with x-coordinates 3 and 2.
Create a new list: The comprehension produces [{'x': 3, 'y': 1}, {'x': 2, 'y': 2}].
Sort with a lambda key: lambda p: p['x'] returns 3 for the first remaining point and 2 for the second, so the point with x equal to 2 comes first.
[{'x': 2, 'y': 2}, {'x': 3, 'y': 1}]
[{'x': 2, 'y': 2}, {'x': 3, 'y': 1}]Syntax Traps and Debugging
These features are compact, so a small syntax error can change or prevent the operation. Debug by separating the pieces: identify the lambda parameter and returned expression, then identify the comprehension expression, for clause, and optional condition. After that, trace one source element at a time to predict what should happen.
Forgetting the colon in a lambda expression
A lambda needs a parameter followed by a colon and then the expression it returns.
Fix:
lambda p: p['x']Putting the comprehension clauses in the wrong order
The comprehension begins with the output expression, followed by for item in source_list.
Fix:
[i * 2 for i in listone]Treating a lambda as if it creates a list
A lambda takes an input and returns an output. It does not create a new list by itself.
Fix:
Use a list comprehension when the goal is to collect transformed values into a new list.Confusing the sort key with the original element
The x-coordinate is only the temporary comparison value. The complete point is still the element that is reordered.
Fix:
Read lambda p: p['x'] as extract the x-coordinate for comparison, not replace each point with its x-coordinate.
Practice and Review
Given points = [{'x': 5, 'y': 0}, {'x': 2, 'y': 3}, {'x': 4, 'y': 1}], write code that creates a new list containing only points whose x-coordinate is greater than 2, then sorts that new list by the y-coordinate.
Hints
- Use a list comprehension to filter the points.
- The lambda parameter should represent one point.
- The sort key should extract the y-coordinate.
What do you think happens?
What is the result of [i * 2 for i in [2, 3, 4] if i > 2]?
Reveal answer
Answer: [6, 8]
The condition removes 2. The expression then doubles 3 and 4, producing 6 and 8.
- A lambda used as sort()'s key receives each element and returns a temporary comparison value. Sorting uses that value to choose the order, but the original elements remain the items being reordered. A list comprehension follows the pattern [expression for item in list if condition] and creates a new list. The expression transforms included items, while the optional condition filters them. When debugging, check lambda colons, comprehension clause order, and the result produced for each source element.
Key Takeaways
- A lambda sort key transforms each element into a temporary value used for comparison.
- The original list elements remain intact in form while their order is changed.
- List comprehensions create new lists by transforming and optionally filtering source elements.
- Tracing each element through the lambda or comprehension makes output easier to predict and syntax errors easier to find.