Python operator: Operations as Functions

Published on: August 11, 2026
Reading time: 4 minutes
Programming code representing operations as functions with Python operator

The operator module exposes efficient functions equivalent to Python’s intrinsic operators. operator.add(a, b) performs the same operation as a + b, while operator.getitem(obj, key) corresponds to obj[key]. Tools such as itemgetter(), attrgetter(), and methodcaller() create reusable callables for sorting, grouping, mapping, callbacks, and behavior tables.

The goal is not to replace ordinary syntax. In a direct expression, a + b is clearer. The module becomes valuable when an API expects a function, including sorted(), map(), reduce(), and itertools.groupby().

Arithmetic operators as functions

import operator

print(operator.add(10, 5))
print(operator.sub(10, 5))
print(operator.mul(10, 5))
print(operator.truediv(10, 5))
print(operator.pow(2, 8))

These functions honor an object’s special methods. add() may add numbers, concatenate sequences, or invoke a custom __add__().

Using operator with reduce

from functools import reduce
from operator import mul

product = reduce(mul, [2, 3, 4], 1)
print(product)

Use sum() for ordinary addition. Choose reduce() when the operation and identity are explicit and the result remains readable.

Comparison callables

lt, le, eq, ne, ge, and gt implement rich comparisons.

comparisons = {
    "less": operator.lt,
    "equal": operator.eq,
    "greater": operator.gt,
}

result = comparisons["greater"](10, 3)

Custom objects may return values other than strict booleans. Convert with bool() when a consumer requires an actual truth value.

Identity and None

is_() and is_not() test object identity. Python 3.14 added is_none() and is_not_none(), which are convenient in filters.

from operator import is_not_none

values = [10, None, 20, None, 30]
valid = list(filter(is_not_none, values))

Identity is not equality. Use identity for sentinels such as None and eq() for value comparison.

Truth tests

truth(obj) is equivalent to bool(obj), and not_(obj) is equivalent to not obj.

active = list(filter(operator.truth, [0, 1, "", "ok", [], [1]]))

This removes zero, empty collections, empty strings, and None together. Do not use it when zero or empty values are meaningful.

itemgetter for mappings and sequences

itemgetter() builds a callable that invokes __getitem__(). It is widely used as a sort key.

from operator import itemgetter

products = [
    {"name": "A", "price": 30},
    {"name": "B", "price": 10},
    {"name": "C", "price": 20},
]

ordered = sorted(products, key=itemgetter("price"))

Multiple items produce a tuple and support multi-field sorting.

key = itemgetter("category", "price")

Slices with itemgetter

The argument can be any key accepted by the target, including a slice.

last_three = itemgetter(slice(-3, None))
print(last_three([1, 2, 3, 4, 5]))

This is elegant in small pipelines. Use a named function when validation, documentation, or fallback logic is needed.

attrgetter for attributes

attrgetter() retrieves one or several attributes and accepts dotted paths.

from operator import attrgetter

ordered_users = sorted(users, key=attrgetter("profile.name"))

If an attribute is missing, the normal exception propagates. Write an explicit function when optional values require a default.

methodcaller for method invocation

methodcaller() creates a function that invokes a named method with fixed arguments.

from operator import methodcaller

names = ["  Alice ", " BOB", "carol "]
clean = list(map(methodcaller("strip"), names))
lower = list(map(methodcaller("lower"), clean))

Do not allow arbitrary user-provided method names without a strict allowlist.

operator.call

Since Python 3.11, call(obj, *args, **kwargs) invokes a callable.

tasks = [lambda: "A", lambda: "B"]
results = list(map(operator.call, tasks))

Direct syntax is clearer in normal code. call() is useful when the act of calling must itself be passed as a function.

Sequence operations

contains(a, b) performs b in a; note the reversed operand order. countOf(), indexOf(), and concat() offer other sequence operations.

print(operator.contains([1, 2, 3], 2))
print(operator.countOf("banana", "a"))
print(operator.indexOf([10, 20, 30], 20))

The argument order of contains() is a frequent source of bugs.

getitem, setitem, and delitem

data = {"active": False}
operator.setitem(data, "active", True)
print(operator.getitem(data, "active"))
operator.delitem(data, "active")

These functions are useful in generic behavior tables. Direct syntax remains preferable when the key is known at the call site.

length_hint

length_hint() asks an iterable for an actual length or estimate.

iterator = iter(range(100))
estimate = operator.length_hint(iterator)

The result is only a hint for preallocation. Never use it as a trusted count or security boundary.

Bitwise and matrix operations

The module includes and_(), or_(), xor(), invert(), shifts, and matmul(). The underscore in and_ and or_ avoids keyword conflicts.

These functions invoke the same special methods as their syntax and can operate on sets, arrays, and numeric-library objects.

In-place operations

iadd(), imul(), and related functions invoke in-place methods. Mutable objects may be changed. Immutable objects produce a new value but the caller’s variable is not reassigned automatically.

text = "Hello"
new = operator.iadd(text, " world")
print(text)  # unchanged

items = [1, 2]
operator.iadd(items, [3])
print(items)  # mutated

Always retain the returned value in generic code when mutability is unknown.

A safe operation table

OPERATIONS = {
    "+": operator.add,
    "-": operator.sub,
    "*": operator.mul,
    "/": operator.truediv,
}

def calculate(a, symbol, b):
    try:
        function = OPERATIONS[symbol]
    except KeyError:
        raise ValueError("operation not allowed")
    return function(a, b)

An explicit allowlist is safer than eval(). Still validate types, divide-by-zero, numeric limits, and computational cost.

Performance and readability

itemgetter() and attrgetter() are efficient, but their speed advantage over lambdas should rarely be the primary design concern. Choose the form that communicates the rule best.

A lambda or named function is better when the key requires transformation, defaults, or error handling.

Common mistakes

  • Using the module where direct syntax is clearer.
  • Reversing contains() arguments.
  • Confusing identity with equality.
  • Discarding an in-place return value for an immutable object.
  • Filtering with truth() when zero is valid.
  • Using getters for optional fields without handling failures.
  • Using eval() instead of an allowlisted operation table.
  • Use getters for sorting and grouping keys.
  • Use named functions when logic is involved.
  • Allowlist operations selected by users.
  • Keep the return value of in-place functions.
  • Use identity only for sentinels.
  • Test custom objects and exception behavior.
  • Prioritize clarity over micro-optimization.

Continue with Python bisect, Python statistics, Python fractions, Python Decimal, and Python inspect.

See the official operator documentation and the functools documentation.

Conclusion

The operator module turns language operations into callable values, simplifying sorting, grouping, mapping, and behavior tables. It is most useful in functional APIs; direct syntax remains the clearest option for ordinary expressions.

Share:

Facebook
WhatsApp
Twitter
LinkedIn

Article content

    Related articles

    Three-dimensional alphabet representing Unicode normalization with Python unicodedata
    Advanced Python
    Foto de perfil de Leandro Hirt da Academify

    Python unicodedata: Normalize Unicode

    Learn Python unicodedata to normalize Unicode, inspect names, categories, numeric values, combining marks, bidirectional classes, and width.

    Ler mais

    Tempo de leitura: 5 minutos
    11/08/2026
    Server network representing resource management with Python ExitStack
    Advanced Python
    Foto de perfil de Leandro Hirt da Academify

    Python ExitStack: Manage Resources

    Learn Python ExitStack to manage dynamic files, connections, callbacks, and cleanup safely in predictable reverse order.

    Ler mais

    Tempo de leitura: 5 minutos
    11/08/2026
    Locked folder representing file types and permissions with Python stat
    Advanced Python
    Foto de perfil de Leandro Hirt da Academify

    Python stat: File Types and Permissions

    Learn Python stat to interpret file types, permissions, links, timestamps, Windows attributes, and Unix flags safely and portably.

    Ler mais

    Tempo de leitura: 5 minutos
    10/08/2026
    Laptop with code representing automatic documentation with Python pydoc
    Advanced Python
    Foto de perfil de Leandro Hirt da Academify

    Python pydoc: Automatic Documentation

    Learn Python pydoc to generate terminal help, HTML, search, and a local documentation server safely from docstrings.

    Ler mais

    Tempo de leitura: 6 minutos
    10/08/2026
    International keyboard representing numbers, currency, and dates with Python locale
    Advanced Python
    Foto de perfil de Leandro Hirt da Academify

    Python locale: Numbers, Currency, and Dates

    Learn Python locale to format and parse numbers, currency, dates, encodings, and cultural sorting without concurrency mistakes.

    Ler mais

    Tempo de leitura: 6 minutos
    09/08/2026
    Monitor and network representing system information with Python platform
    Advanced Python
    Foto de perfil de Leandro Hirt da Academify

    Python platform: System Information

    Learn Python platform to identify operating systems, architecture, Linux distributions, Python versions, and runtime environments safely.

    Ler mais

    Tempo de leitura: 6 minutos
    09/08/2026