Sorting, Minimum and Maximum

Sorting, Minimum and Maximum in Python min, max, and sorted all need the objects to be orderable. Learn More about it here.

Section 72.1: Make custom classes orderable

min, max, and sorted all need the objects to be orderable. To be properly orderable, the class needs to define all of the 6 methods lt, gt, ge, le, ne and eq:

class IntegerContainer(object):
def init(self, value):
self.value = value
def repr(self):
return "{}({})".format(self.class.name, self.value)
def lt(self, other):
print('{!r} - Test less than {!r}'.format(self, other))
return self.value < other.value def le(self, other): print('{!r} - Test less than or equal to {!r}'.format(self, other)) return self.value <= other.value def gt(self, other): print('{!r} - Test greater than {!r}'.format(self, other)) return self.value > other.value
def ge(self, other):
print('{!r} - Test greater than or equal to {!r}'.format(self, other))
return self.value >= other.value
def eq(self, other):
print('{!r} - Test equal to {!r}'.format(self, other))
return self.value == other.value
def ne(self, other):
print('{!r} - Test not equal to {!r}'.format(self, other))
return self.value != other.value

Though implementing all these methods would seem unnecessary, omitting some of them will make your code prone to bugs.

Examples:
alist = [IntegerContainer(5), IntegerContainer(3), IntegerContainer(10), IntegerContainer(7)
]
res = max(alist)
Out: IntegerContainer(3) - Test greater than IntegerContainer(5)
IntegerContainer(10) - Test greater than IntegerContainer(5)
IntegerContainer(7) - Test greater than IntegerContainer(10) print(res)
Out: IntegerContainer(10)
res = min(alist)
Out: IntegerContainer(3) - Test less than IntegerContainer(5)
IntegerContainer(10) - Test less than IntegerContainer(3)

GoalKicker.com – Python® Notes for Professionals 362

IntegerContainer(7) - Test less than IntegerContainer(3) print(res)
Out: IntegerContainer(3)
res = sorted(alist)
Out: IntegerContainer(3) - Test less than IntegerContainer(5)
IntegerContainer(10) - Test less than IntegerContainer(3)
IntegerContainer(10) - Test less than IntegerContainer(5)
IntegerContainer(7) - Test less than IntegerContainer(5)
IntegerContainer(7) - Test less than IntegerContainer(10) print(res)
Out: [IntegerContainer(3), IntegerContainer(5), IntegerContainer(7), IntegerContainer(10)]

sorted with reverse=True also uses lt:

res = sorted(alist, reverse=True)
Out: IntegerContainer(10) - Test less than IntegerContainer(7)
IntegerContainer(3) - Test less than IntegerContainer(10)
IntegerContainer(3) - Test less than IntegerContainer(10)
IntegerContainer(3) - Test less than IntegerContainer(7)
IntegerContainer(5) - Test less than IntegerContainer(7)
IntegerContainer(5) - Test less than IntegerContainer(3) print(res)
Out: [IntegerContainer(10), IntegerContainer(7), IntegerContainer(5), IntegerContainer(3)]

But sorted can use gt instead if the default is not implemented:

del IntegerContainer.lt # The IntegerContainer no longer implements "less than"
res = min(alist)
Out: IntegerContainer(5) - Test greater than IntegerContainer(3)
IntegerContainer(3) - Test greater than IntegerContainer(10)
IntegerContainer(3) - Test greater than IntegerContainer(7) print(res)
Out: IntegerContainer(3)

Sorting methods will raise a TypeError if neither lt nor gt are implemented:

del IntegerContainer.gt # The IntegerContainer no longer implements "greater then"
res = min(alist)
TypeError: unorderable types: IntegerContainer() < IntegerContainer()

functools.total_ordering decorator can be used simplifying the effort of writing these rich comparison methods. If you decorate your class with total_ordering, you need to implement eq, ne and only one of the lt, le, ge or gt, and the decorator will fill in the rest:

import functools
@functools.total_ordering
class IntegerContainer(object):
def init(self, value):
self.value = value
def repr(self):
return "{}({})".format(self.class.name, self.value)

GoalKicker.com – Python® Notes for Professionals 363

def lt(self, other):
print('{!r} - Test less than {!r}'.format(self, other))
return self.value < other.value def eq(self, other): print('{!r} - Test equal to {!r}'.format(self, other)) return self.value == other.value def ne(self, other): print('{!r} - Test not equal to {!r}'.format(self, other)) return self.value != other.value IntegerContainer(5) > IntegerContainer(6)
Output: IntegerContainer(5) - Test less than IntegerContainer(6)
Returns: False
IntegerContainer(6) > IntegerContainer(5)
Output: IntegerContainer(6) - Test less than IntegerContainer(5)
Output: IntegerContainer(6) - Test equal to IntegerContainer(5)
Returns True

Notice how the > (greater than) now ends up calling the less than method, and in some cases even the eq method. This also means that if speed is of great importance, you should implement each rich comparison method yourself.

Section 72.2: Special case: dictionaries

Getting the minimum or maximum or using sorted depends on iterations over the object. In the case of dict, the iteration is only over the keys:

adict = {'a': 3, 'b': 5, 'c': 1}
min(adict)
Output: 'a' max(adict)
Output: 'c' sorted(adict)
Output: ['a', 'b', 'c']

To keep the dictionary structure, you have to iterate over the .items():

min(adict.items())
Output: ('a', 3) max(adict.items())
Output: ('c', 1) sorted(adict.items())
Output: [('a', 3), ('b', 5), ('c', 1)]

For sorted, you could create an OrderedDict to keep the sorting while having a dict-like structure:

from collections import OrderedDict
OrderedDict(sorted(adict.items()))
Output: OrderedDict([('a', 3), ('b', 5), ('c', 1)]) res = OrderedDict(sorted(adict.items()))
res['a']
Output: 3

By value

GoalKicker.com – Python® Notes for Professionals
364

Again this is possible using the key argument:

min(adict.items(), key=lambda x: x[1])

Output: (‘c’, 1)

max(adict.items(), key=operator.itemgetter(1))

Output: (‘b’, 5)

sorted(adict.items(), key=operator.itemgetter(1), reverse=True)

Output: [(‘b’, 5), (‘a’, 3), (‘c’, 1)]

Section 72.3: Using the key argument

Finding the minimum/maximum of a sequence of sequences is possible:

list_of_tuples = [(0, 10), (1, 15), (2, 8)]
min(list_of_tuples)

Output: (0, 10)

but if you want to sort by a specific element in each sequence use the key-argument:

min(list_of_tuples, key=lambda x: x[0])

Output: (0, 10)

min(list_of_tuples, key=lambda x: x[1])

Output: (2, 8)

sorted(list_of_tuples, key=lambda x: x[0])

Output: [(0, 10), (1, 15), (2, 8)]

sorted(list_of_tuples, key=lambda x: x[1])

Output: [(2, 8), (0, 10), (1, 15)]

Sorting by first element

Sorting by second element

Sorting by first element (increasing)

Sorting by first element

import operator
The operator module contains efficient alternatives to the lambda function max(list_of_tuples, key=operator.itemgetter(0)) # Sorting by first element
Output: (2, 8)
max(list_of_tuples, key=operator.itemgetter(1)) # Sorting by second element

Output: (1, 15)

sorted(list_of_tuples, key=operator.itemgetter(0), reverse=True) # Reversed (decreasing)

Output: [(2, 8), (1, 15), (0, 10)]

sorted(list_of_tuples, key=operator.itemgetter(1), reverse=True) # Reversed(decreasing)

Output: [(1, 15), (0, 10), (2, 8)]

Section 72.4: Default Argument to max, min

You can’t pass an empty sequence into max or min:

min([])

ValueError: min() arg is an empty sequence

However, with Python 3, you can pass in the keyword argument default with a value that will be returned if the sequence is empty, instead of raising an exception:

GoalKicker.com – Python® Notes for Professionals 365

max([], default=42)

Output: 42

max([], default=0)

Output: 0

Section 72.5: Getting a sorted sequence

Using one sequence:

sorted((7, 2, 1, 5)) # tuple

Output: [1, 2, 5, 7]

sorted(['c', 'A', 'b']) # list

Output: [‘A’, ‘b’, ‘c’]

sorted({11, 8, 1}) # set

Output: [1, 8, 11]

sorted({'11': 5, '3': 2, '10': 15}) # dict

Output: [’10’, ’11’, ‘3’] # only iterates over the keys

sorted(‘bdca’) # string

Output: [‘a’,’b’,’c’,’d’]

The result is always a new list; the original data remains unchanged.

Section 72.6: Extracting N largest or N smallest items from an iterable

To find some number (more than one) of largest or smallest values of an iterable, you can use the nlargest and nsmallest of the heapq module:

import heapq

get 5 largest items from the range

heapq.nlargest(5, range(10))

Output: [9, 8, 7, 6, 5]

heapq.nsmallest(5, range(10))

Output: [0, 1, 2, 3, 4]

This is much more efficient than sorting the whole iterable and then slicing from the end or beginning. Internally these functions use the binary heap priority queue data structure, which is very efficient for this use case.

Like min, max and sorted, these functions accept the optional key keyword argument, which must be a function that, given an element, returns its sort key.

Here is a program that extracts 1000 longest lines from a file:

import heapq
with open(filename) as f:
longest_lines = heapq.nlargest(1000, f, key=len)

Here we open the file, and pass the file handle f to nlargest. Iterating the file yields each line of the file as a separate string; nlargest then passes each element (or line) is passed to the function len to determine its sort key.

GoalKicker.com – Python® Notes for Professionals 366

len, given a string, returns the length of the line in characters.

This only needs storage for a list of 1000 largest lines so far, which can be contrasted with

longest_lines = sorted(f, key=len)[1000:]

which will have to hold the entire file in memory.

Section 72.7: Getting the minimum or maximum of several values

min(7,2,1,5)

Output: 1

max(7,2,1,5)

Output: 7

Section 72.8: Minimum and Maximum of a sequence

Getting the minimum of a sequence (iterable) is equivalent of accessing the first element of a sorted sequence:

min([2, 7, 5])

Output: 2

sorted([2, 7, 5])[0]

Output: 2

The maximum is a bit more complicated, because sorted keeps order and max returns the first encountered value.

In case there are no duplicates the maximum is the same as the last element of the sorted return:

max([2, 7, 5])

Output: 7

sorted([2, 7, 5])[-1]

Output: 7

But not if there are multiple elements that are evaluated as having the maximum value:

class MyClass(object):
def init(self, value, name):
self.value = value
self.name = name
def lt(self, other):
return self.value < other.value
def repr(self):
return str(self.name)
sorted([MyClass(4, 'first'), MyClass(1, 'second'), MyClass(4, 'third')])

Output: [second, first, third]

max([MyClass(4, 'first'), MyClass(1, 'second'), MyClass(4, 'third')])

Output: first

Any iterable containing elements that support < or > operations are allowed.

Must Read Python Interview Questions

200+ Python Tutorials With Coding Examples

Python Language Basics TutorialPython String Representations of Class Instances
Python For Beginners TutorialPython Debugging Tutorial
Python Data Types TutorialReading and Writing CSV File Using Python
Python Indentation TutorialWriting to CSV in Python from String/List
Python Comments and Documentation TutorialPython Dynamic Code Execution Tutorial
Python Date And Time TutorialPython Code Distributing using Pyinstaller
Python Date Formatting TutorialPython Data Visualization Tutorial
Python Enum TutorialPython Interpreter Tutorial
Python Set TutorialPython Args and Kwargs
Python Mathematical Operators TutorialPython Garbage Collection Tutorial
Python Bitwise Operators TutorialPython Pickle Data Serialisation
Python Bolean Operators TutorialPython Binary Data Tutorial
Python Operator Precedance TutorialPython Idioms Tutorial
Python Variable Scope And Binding TutorialPython Data Serialization Tutorial
Python Conditionals TutorialPython Multiprocessing Tutorial
Python Comparisons TutorialPython Multithreading Tutorial
Python Loops TutorialPython Processes and Threads
Python Arrays TutorialPython Concurrency Tutorial
Python Multidimensional Arrays TutorialPython Parallel Computation Tutorial
Python List TutorialPython Sockets Module Tutorial
Python List Comprehensions TutorialPython Websockets Tutorial
Python List Slicing TutorialSockets Encryption Decryption in Python
Python Grouby() TutorialPython Networking Tutorial
Python Linked Lists TutorialPython http Server Tutorial
Linked List Node TutorialPython Flask Tutorial
Python Filter TutorialIntroduction to Rabbitmq using Amqpstorm Python
Python Heapq TutorialPython Descriptor Tutorial
Python Tuple TutorialPython Tempflile Tutorial
Python Basic Input And Output TutorialInput Subset and Output External Data Files using Pandas in Python
Python Files And Folders I/O TutorialUnzipping Files in Python Tutorial
Python os.path TutorialWorking with Zip Archives in Python
Python Iterables And Iterators Tutorialgzip in Python Tutorial
Python Functions TutorialStack in Python Tutorial
Defining Functions With List Arguments In PythonWorking with Global Interpreter Lock (GIL)
Functional Programming In PythonPython Deployment Tutorial
Partial Functions In PythonPython Logging Tutorial
Decorators Function In PythonPython Server Sent Events Tutorial
Python Classes TutorialPython Web Server Gateway Interface (WSGI)
Python Metaclasses TutorialPython Alternatives to Switch Statement
Python String Formatting TutorialPython Packing and Unpacking Tutorial
Python String Methods TutorialAccessing Python Sourcecode and Bytecode
Using Loops Within Functions In PythonPython Mixins Tutorial
Python Importing Modules TutorialPython Attribute Access Tutorial
Difference Betweeb Module And Package In PythonPython Arcpy Tutorial
Python Math Module TutorialPython Abstract Base Class Tutorial
Python Complex Math TutorialPython Plugin and Extension Classes
Python Collections Module TutorialPython Immutable Datatypes Tutorial
Python Operator Module TutorialPython Incompatibilities Moving from Python 2 to Python 3
Python JSON Module TutorialPython 2to3 Tool Tutorial
Python Sqlite3 Module TutorialNon-Official Python implementations
Python os Module TutorialPython Abstract Syntax Tree
Python Locale Module TutorialPython Unicode and Bytes
Python Itertools Module TutorialPython Serial Communication (pyserial)
Python Asyncio Module TutorialNeo4j and Cypher using Py2Neo
Python Random Module TutorialBasic Curses with Python
Python Functools Module TutorialTemplates in Python
Python dis Module TutorialPython Pillow
Python Base64 Module TutorialPython CLI subcommands with precise help output
Python Queue Module TutorialPython Database Access
Python Deque Module TutorialConnecting Python to SQL Server
Python Webbrowser Module TutorialPython and Excel
Python tkinter TutorialPython Turtle Graphics
Python pyautogui Module TutorialPython Persistence
Python Indexing And Slicing TutorialPython Design Patterns
Python Plotting With Matplotlib TutorialPython hashlib
Python Graph Tool TutorialCreating a Windows Service Using Python
Python Generators TutorialMutable vs Immutable (and Hashable) in Python
Python Reduce TutorialPython configparser
Python Map Function TutorialPython Optical Character Recognition
Python Exponentiation TutorialPython Virtual Environments
Python Searching TutorialPython Virtual Environment – virtualenv
Sorting Minimum And Maximum In PythonPython Virtual environment with virtualenvwrapper
Python Print Function TutorialCreate virtual environment with virtualenvwrapper in windows
Python Regular Expressions Regex TutorialPython sys Tutorial
Copying Data In Python TutorialChemPy – Python package
Python Context Managers (“with” Statement) TutorialPython pygame
Python Name Special Variable TutorialPython pyglet
Checking Path Existence And Permissions In PythonWorking with Audio in Python
Creating Python Packages TutorialPython pyaudio
Usage of pip Module In Python TutorialPython shelve
Python PyPi Package Manager TutorialIoT Programming with Python and Raspberry PI
Parsing Command Line Arguments In Pythonkivy – Cross-platform Python Framework for NUI Development
Python Subprocess Library TutorialPandas Transform
Python setup.py TutorialPython vs. JavaScript
Python Recursion TutorialCall Python from C#
Python Type Hints TutorialPython Writing Extensions
Python Exceptions TutorialPython Lex-Yacc
Raise Custom Exceptions In PythonPython Unit Testing
Python Commonwealth Exceptions TutorialPython py.test
Python urllib TutorialPython Profiling
Web Scraping With Python TutorialPython Speed of Program
Python HTML Parsing TutorialPython Performance Optimization
Manipulating XML In PythonPython Security and Cryptography
Python Requests Post TutorialSecure Shell Connection in Python
Python Distribution TutorialPython Anti Patterns
Python Property Objects TutorialPython Common Pitfalls
Python Overloading TutorialPython Hidden Features
Python Polymorphism TutorialPython For Machine Learning
Python Method Overriding TutorialPython Interview Questions And Answers For Experienced
Python User Defined Methods TutorialPython Coding Interview Questions And Answers
Python Programming Tutorials With Examples

Other Python Tutorials

Leave a Comment