abs() в Python: абсолютное значение числа
Функция abs() в Python возвращает модуль числа, то есть его расстояние от нуля без учета знака. Ниже показано, как она работает с целыми, вещественными и комплексными числами, чем отличается от math.fabs(), как добавить поддержку abs своему классу и где функция пригодится на практике.

Содержание статьи
Синтаксис и возвращаемое значение
abs - встроенная функция, импортировать ее не нужно. Она принимает ровно один аргумент:
abs(x)Для положительного числа и нуля результат равен самому числу, для отрицательного - числу с противоположным знаком. Тип результата обычно совпадает с типом аргумента, исключение составляют комплексные числа.
| Тип аргумента | Пример | Результат | Тип результата |
|---|---|---|---|
int | abs(-7) | 7 | int |
float | abs(-2.5) | 2.5 | float |
complex | abs(3 - 4j) | 5.0 | float |
bool | abs(True) | 1 | int |
Fraction | abs(Fraction(-3, 4)) | 3/4 | Fraction |
Decimal | abs(Decimal("-1.50")) | 1.50 | Decimal |
Если передать строку, список или None, функция выбросит TypeError: bad operand type for abs(). Строку с числом сначала нужно преобразовать: abs(int("-15")).
Целые и вещественные числа
С целыми числами abs работает при любом размере значения, так как int в Python не ограничен разрядностью. Для вещественных чисел есть несколько особых случаев, которые полезно знать.
print(abs(-20)) # 20
print(abs(-30.33)) # 30.33
print(abs(-2 ** 100)) # 1267650600228229401496703205376
print(abs(-0.0)) # 0.0
print(abs(float("-inf"))) # inf
print(abs(float("nan"))) # nanОтрицательный ноль, который иногда появляется в вычислениях с float, превращается в обычный. Бесконечность становится положительной, а NaN остается NaN. Обратите внимание на приоритет операций: в записи -2 ** 100 сначала выполняется возведение в степень, потом смена знака. Подробнее о типах чисел в статье числа в Python 3.
Комплексные числа
Для комплексного числа a + bj функция возвращает его модуль: длину вектора от начала координат до точки (a, b). Значение вычисляется по формуле квадратного корня из суммы квадратов a и b и всегда имеет тип float.
z = 3 - 4j
print(abs(z)) # 5.0, так как корень из 9 + 16 равен 5
import math
print(math.hypot(z.real, z.imag)) # 5.0, то же значениеМодуль комплексного числа используют в электротехнике для амплитуды сигнала и в геометрии для расстояния между точками на плоскости. Остальные операции с этим типом разобраны в статье про complex.
Отличие abs() от math.fabs()
В модуле math есть похожая функция fabs(). Результат по значению совпадает, но поведение различается.
| Критерий | abs() | math.fabs() |
|---|---|---|
| Импорт | Не нужен | import math |
| Тип результата для int | int | float |
| Комплексные числа | Поддерживает | TypeError |
| Очень большие int | Точный результат | Округление или OverflowError |
| Свои классы через __abs__ | Работает | Не работает |
import math
print(abs(-5), math.fabs(-5)) # 5 5.0В обычном коде достаточно abs. math.fabs уместна, когда результат обязательно должен быть float.
Поддержка abs() в своем классе
Функция abs вызывает у объекта специальный метод __abs__. Если определить его в классе, экземпляры можно передавать в abs наравне с числами. Пример - двумерный вектор, у которого модулем считается длина.
import math
class Vector:
def __init__(self, x, y):
self.x, self.y = x, y
def __abs__(self):
return math.hypot(self.x, self.y)
print(abs(Vector(6, -8))) # 10.0Другие специальные методы, которые подключают объект к встроенным функциям и операторам, описаны в статье про магические методы.
Практические примеры
abs часто встречается в задачах, где важна величина отклонения, а не его направление.
Разница между двумя значениями
Расстояние между числами на прямой не зависит от порядка вычитания.
plan, fact = 120, 95
print(abs(fact - plan)) # 25Ближайшее значение к заданному
Функция abs в качестве ключа для min() находит элемент с наименьшим отклонением от цели.
temps = [12, 7, 19, 25]
print(min(temps, key=lambda t: abs(t - 20))) # 19Сортировка по модулю и обработка списка
abs принимает только одно число. Чтобы получить модули всех элементов, используйте map() или генератор, а для сортировки передайте функцию в параметр key.
nums = [-5, 3, -1, 4]
print(list(map(abs, nums))) # [5, 3, 1, 4]
print(sorted(nums, key=abs)) # [-1, 3, 4, -5]Сравнение дробных чисел
Из-за погрешности представления float выражение 0.1 + 0.2 == 0.3 ложно. Числа сравнивают через модуль разности и малый допуск или функцией math.isclose().
import math
a = 0.1 + 0.2
print(abs(a - 0.3) < 1e-9) # True
print(math.isclose(a, 0.3)) # TrueЧастые вопросы
Короткие ответы на вопросы о функции abs.
Нужно ли импортировать abs?
Нет, это встроенная функция, она доступна в любом месте программы. Импорт требуется только для math.fabs().
Как получить модуль каждого элемента списка?
Передать список в abs нельзя, будет TypeError. Используйте [abs(x) for x in nums] или list(map(abs, nums)).
Почему abs от комплексного числа возвращает float?
Модуль комплексного числа - это длина вектора, то есть вещественное значение. Знак у такой величины не определен, поэтому результат не может быть комплексным.
Как сделать число отрицательным независимо от знака?
Поставьте минус перед abs: -abs(x). Для любого x результат будет меньше или равен нулю.