Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

This lesson is for members only. Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Hint: You can adjust the default video playback speed in your account settings.
Hint: You can set your subtitle preferences in your account settings.
Sorry! Looks like there’s an issue with video playback 🙁 This might be due to a temporary outage or because of a configuration issue with your browser. Please see our video player troubleshooting guide to resolve the issue.

Exploring the Role of .__lt__() and .__gt__() in min() and max()

00:00 Exploring the Role of .__lt__() and .__gt__() in min() and max(). As you’ve learned so far, the built-in min() and max() functions are versatile enough to work with values of various data types, such as numbers and strings.

00:15 The secret behind this flexibility is that min() and max() embrace Python’s duck typing philosophy by relying on the .__lt__() and .__gt__() special methods.

00:26 These methods are part of what Python calls rich comparison methods. Specifically, .__lt__() and .__gt__() support the less than (<) and greater than (>) operators, respectively. But what’s the meaning of support here?

00:39 When Python encounters a line such as seen on-screen, internally it does this. The takeaway is that you can use min() and max() with values of any data type that implement .__lt__() and .__gt__().

00:53 That’s why these functions work with values of all Python’s built-in data types.

01:12 As you can see, Python’s built-in data types implement the .__lt__() and .__gt__() special methods. So, you can feed any of these data types into min() and max(), with the only condition being that the involved data types are comparable.

01:30 You can also make instances of custom classes compatible with min() and max(). To achieve this, you need to provide your own implementations of .__lt__() and .__gt__().

01:42 Consider the Person class seen on-screen as an example of this compatibility.

02:15 Note that the implementation of both dunder methods requires an argument that’s typically named other. This argument represents the second operand in the underlying comparison operations. For example, an expression such as x < y, x will be self and y will be other. Here, the dunder methods return the result of comparing two people’s .birth_date attributes. You can see this working in practice on-screen.

03:01 You can process Person objects with min() and max() because the class provides implementations of .__lt__() and .__gt__().

03:09 The call to min() returns the youngest person, and the call to max() returns the oldest. The .__lt__() and .__gt__() methods provides support for only two comparison operators, < and >.

03:25 If you ever want a class that provides all the comparison operators, but you only want to write a few special methods, then you can use the @functools.total_ordering decorator.

03:36 If you have a class that defines .__eq__() and other rich comparison methods, then this decorator will automatically supply the rest of the comparison methods. Note that if a given custom class doesn’t provide these methods, then its instances won’t support min() and max() operations.

04:13 Because the Number class doesn’t provide suitable implementations of .__lt__() and .__gt__(), min() and max() respond with a TypeError.

04:21 The error message tells you that the comparison operations aren’t supported in the current class.

04:29 In the next section of the course, you’ll see how to emulate min() and max() with pure Python code.

Become a Member to join the conversation.