0%

Representing and Comparing Objects · practice

Order Only When It Fits

Hashing answers whether a can be found in a set or . Ordering answers a separate question: which of two values comes first?

sorted() needs an ordering, and < on a new class raises by default:

class Points:
    def __init__(self, amount):
        self.amount = amount


sorted([Points(5), Points(1), Points(3)])

A natural order belongs on the value

Points has one uncontroversial order: three points is less than five points. Define __lt__, which Python uses for < and sorting:

Try it

Returning NotImplemented for another type gives Python the opportunity to try the other operand and ultimately raise a useful .

A situational order belongs at the call

A Question has no single natural order. A report might want cheapest first; another wants alphabetical prompts. Neither is the permanent meaning of question_a < question_b.

Use a key at the sorting site:

Try it

The call states what this particular order means and leaves another caller free to choose differently.

A report needs questions listed from cheapest to most expensive. What is the better tool?

Define __lt__ only when one ordering is genuinely the meaning of the value. Otherwise keep the order explicit with a key.

The exercise applies both decisions: Points gains its natural order, while Question remains unordered and a report function sorts it by points.

Task

Add only the ordering each genuinely owns.

Give Points an __lt__ comparing its amount and returning NotImplemented for another type. sorted() should then order a of Points without a key.

Do not give Question an ordering . Write by_points(questions), returning a new list sorted from cheapest to most expensive with a key . Leave the original list unchanged.