Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

For ordinary Python integers and floats, you can get an absolute value with a conditional expression: x if x >= 0 else -x. It returns x when it is zero or positive, and the negation of x otherwise. That covers most manual exercises and simple scripts. It does not cover every type Python’s abs() accepts, and the sections below explain where the manual approach needs a different method.

Two equivalent ways to write the manual version

The conditional expression

x = -7
absolute_value = x if x >= 0 else -x
print(absolute_value)   # 7

y = 3.5
print(y if y >= 0 else -y)   # 3.5

Python evaluates the condition first and then returns either the value before else or the value after it. Using >= 0 rather than > 0 means zero is returned unchanged, which is the correct result, so the branch never negates a value that is already at the boundary.

The longer if/else block

If you are writing a teaching example or a function that must be easy to read, the same logic expands to:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
def manual_abs(x):
    if x < 0:
        return -x
    else:
        return x

print(manual_abs(-12))   # 12
print(manual_abs(0))     # 0

Both forms return the same value for every int and float that is not NaN and not negative zero. The differences appear in the edge cases below.

Where the manual approach stops being correct

Complex numbers

Python does not define ordering for complex numbers, so the comparison itself fails:

>>> z = 3 + 4j
>>> z >= 0
TypeError: '>=' not supported between instances of 'complex' and 'int'

The built-in abs(z) returns the magnitude, which is 5.0 for 3 + 4j. If you must avoid abs(), compute the magnitude from the real and imaginary parts with math.hypot(z.real, z.imag). This is a different calculation from the sign flip used for real numbers, and it returns a float.

NaN

Ordered comparisons involving NaN are false, so x >= 0 is false for NaN and the expression falls through to -x. The result is still NaN, but its sign bit is flipped, and nothing raises an error. If NaN can reach your code, decide on a policy and enforce it explicitly, for example:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
import math

def checked_abs(x):
    if math.isnan(x):
        raise ValueError("NaN has no meaningful absolute value here")
    return x if x >= 0 else -x

Replace the exception with a default value or a pass-through if your program needs a different rule. The point is that the choice should be made in code, not left to the comparison.

Negative zero

The value -0.0 satisfies -0.0 >= 0, so the conditional expression returns it unchanged, and it stays -0.0. The built-in abs(-0.0) returns 0.0. Both compare equal to zero, but if you print the value or divide by it, the difference is visible. Use math.fabs or abs() when the sign of zero matters, or add + 0.0 after the negation if you need a positive zero from the manual form.

Standard-library and Decimal alternatives

math.fabs()

math.fabs(x) is part of the standard math module and returns a float. It is a function call rather than a comparison, so it avoids the branch entirely.

import math

print(math.fabs(-7))    # 7.0, a float, not an int
print(math.fabs(-0.0))  # 0.0

The result is always a float, so do not use it where integer output matters. It also rejects complex numbers because the math module works with real-number functions.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Decimal

decimal.Decimal has its own absolute-value method. copy_abs() returns a copy with the sign cleared and does not apply the current context’s rounding, so the digits and exponent are preserved:

from decimal import Decimal

d = Decimal("-2.50")
print(d.copy_abs())   # Decimal('2.50')

Calling abs(d) on a Decimal runs the context’s absolute-value operation, which can round the result to the current precision. If the restriction in your exercise applies only to the built-in function name, copy_abs() is the closest match to the behavior you want. The Decimal type also supports special values such as NaN and the infinities, which follow the same caution as NaN for floats.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Choosing an approach

Input type Recommended expression Result type Notes
int or float, no NaN x if x >= 0 else -x Same type as x Returns -0.0 unchanged for negative zero
float, function call acceptable math.fabs(x) float Rejects complex numbers; always returns a float
complex math.hypot(z.real, z.imag) float Magnitude, not a sign flip; comparison with zero is invalid
Decimal x.copy_abs() Decimal Does not apply context rounding; abs(x) does
NaN possible Check with math.isnan(x) first Depends on the policy you choose Comparisons with NaN are false, so the branch needs an explicit rule

If the exercise is a manual implementation, use the conditional form and state that it is limited to ordered real values. In production code without a restriction, the built-in abs() is the idiomatic choice and handles complex magnitude directly.

Mistakes to avoid

  • Multiplying by -1 unconditionally, which flips the sign of positive values as well.
  • Treating unary negation as absolute value. -x only reverses the sign, so it is correct only when x is already negative.
  • Using x < 0 as a universal test. It fails for complex numbers and returns false for NaN.
  • Expecting math.fabs() to keep an integer type. It returns a float.
  • Calling a complex number’s sign-flip result a magnitude. Use math.hypot on the real and imaginary parts instead.

Version notes

The conditional expression uses stable syntax available in every Python 3 release. The math, decimal, and built-in function pages were checked in October 2026, and the documentation for each page is labelled with a different Python version, so confirm version-specific behavior against the Python release your project uses.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.