Type Casting & Conversion

Python · Lesson 6 of 56 8 min read Updated

Data rarely arrives in the type you need. A form sends the age "19" as text, a CSV file gives you prices as strings, and a sensor reading may come in as "36.6". Before you can add, compare or sort these values, you must turn them into the right type. This is called type conversion, and when you do it on purpose with a function call it is often called casting.

In this lesson you will learn the conversion functions in depth, see which conversions Python does by itself, and write code that turns messy user text into clean numbers without crashing.

Explicit conversion with int(), float() and str()

You met int(), float() and str() in Data Types. They are more forgiving than many beginners expect, and also stricter in a few places:

PythonRun it yourself
print(int("  42 "), int("-7"), int("1_00_000"))
print(int(9.99), int(-9.99), round(-9.99))
print(float("12.5"), float("1e3"), float("  -0.25\n"))
print(str(3.0), str(True), str(None), str([1, 2]))
Output
42 -7 100000
9 -9 -10
12.5 1000.0 -0.25
3.0 True None [1, 2]

What to notice:

  • int() and float() ignore spaces and new lines around the text, accept a + or - sign, and accept underscores between digits, so the lakh grouping 1_00_000 works.
  • int() on a float cuts towards zero: 9.99 becomes 9 and -9.99 becomes -9. If you want the nearest whole number, use round().
  • float("1e3") understands scientific notation, which means 1 times 10 to the power 3.
  • str() works on every value, because every object knows how to describe itself as text.

The strict part is that int() only accepts text that looks like a whole number. int("12.5"), int("12,000") and int("₹500") all raise ValueError. You will handle that properly below.

Implicit conversion: number promotion

Python converts types by itself in only one common situation: arithmetic that mixes number types. The result takes the "wider" type, so no information is lost. This is called numeric promotion. The order is bool, then int, then float, then complex.

PythonRun it yourself
print(1 + 2.0, True + 1, 7 / 7, 2 * (1 + 2j))
print(type(3 + 4.0).__name__, type(True + 2).__name__, type(10 / 2).__name__)
print(1 == 1.0, "5" == 5)
Output
3.0 2 1.0 (2+4j)
float int float
True False

An int plus a float gives a float. True counts as 1. The / operator always returns a float, even for 10 / 2. Comparing 1 == 1.0 is True because the values are equal, but "5" == 5 is False: Python never turns text into a number for you. This is deliberate. Languages that convert silently can produce surprises like "5" + 1 becoming "51"; Python stops with a TypeError instead, so the bug shows up straight away.

bool() and the "False" string trap

bool() follows the truthiness rules: zero, empty strings, empty collections and None are False, and almost everything else is True. The trap is that bool() looks at whether text is empty, not at what it says.

PythonRun it yourself
print(bool("False"), bool("0"), bool(" "), bool(""))

def parse_yes_no(text):
    return text.strip().lower() in {"yes", "y", "true", "1"}

print(parse_yes_no(" Yes "), parse_yes_no("false"), parse_yes_no("0"))
Output
True True True False
True False False

bool("False") is True because the string is not empty. When text from a form or a settings file means yes or no, compare it with the words you accept, as parse_yes_no() does.

Bases and characters

int() takes an optional second argument, the base of the number written in the text. Base 2 is binary, 8 is octal and 16 is hexadecimal. The functions bin(), oct() and hex() go the other way and return text. ord() gives a character's Unicode number and chr() turns a number back into a character.

PythonRun it yourself
print(int("1010", 2), int("ff", 16), int("777", 8), int("0x1f", 0))
print(bin(10), hex(255), oct(8))
print(ord("A"), chr(8377))
Output
10 255 511 31
0b1010 0xff 0o10
65 ₹

Base 0 is special: Python reads the prefix (0b, 0o, 0x) to decide the base itself. Code point 8377 is the rupee sign.

Parsing user text safely

Real input is messy. Someone types ₹1,299, another person types 1299.50, and a third leaves the box empty. The professional pattern is: clean the text, try the conversion, and catch ValueError instead of checking every character first. Python programmers call this style EAFP, "easier to ask forgiveness than permission".

PythonRun it yourself
def parse_rupees(text):
    """Turn text like '₹1,299.50' into a float, or return None if it is not a price."""
    cleaned = text.strip().replace("₹", "").replace(",", "")
    try:
        amount = float(cleaned)
    except ValueError:
        return None
    if amount < 0:
        return None
    return amount

for entry in ["₹1,299", " 450.75 ", "1299.50", "", "free", "-20"]:
    print(repr(entry), "->", parse_rupees(entry))
Output
'₹1,299' -> 1299.0
' 450.75 ' -> 450.75
'1299.50' -> 1299.5
'' -> None
'free' -> None
'-20' -> None

Why not use text.isdigit() first? Because it gives the wrong answer in both directions. "-5".isdigit() is False, yet int("-5") works fine. And "²".isdigit() is True (it is a superscript digit), yet int("²") raises ValueError. A try block asks the real converter, so it is always right.

Exact numbers: Decimal and Fraction

Floats are not exact, so money and ratios often use the decimal and fractions modules. Convert to them from strings, not floats, to avoid copying a float's tiny error. You learned the money side in Numbers & Math.

PythonRun it yourself
from decimal import Decimal
from fractions import Fraction

print(Decimal("0.1") + Decimal("0.2"))
print(float(Decimal("2.50")), int(Decimal("7.9")))
print(Fraction("3/4") + Fraction(1, 4))
print(Fraction(0.1))
Output
0.3
2.5 7
1
3602879701896397/36028797018963968

The last line shows the problem with starting from a float: 0.1 is really stored as that huge fraction. Fraction("0.1") would give the clean 1/10.

Common mistakes

  • Converting decimal text with int(). int("12.5") fails. Use float(), or int(float(text)) if you really want to drop the decimals.
  • Expecting bool("False") to be False. Any non-empty string is true. Compare the text instead.
  • Forgetting to convert back. "Total: " + 450 fails. Use an f-string: f"Total: {450}".
  • Checking with isdigit() instead of try. It rejects negative numbers and accepts characters that int() cannot read.
  • Very long digit strings. Current Python versions (3.11 and later) make int() refuse text with more than 4,300 digits by default, to protect servers from slow conversions. sys.set_int_max_str_digits() raises the limit if you really need it.

Key points

  • int(), float(), str() and bool() convert values on purpose; this is explicit conversion or casting.
  • int() ignores surrounding spaces and underscores, but rejects decimals, commas and symbols; on a float it cuts towards zero.
  • Python only converts implicitly between number types, following bool, int, float, complex.
  • bool() checks emptiness, so bool("False") is True.
  • Parse messy text by cleaning it and catching ValueError; never use eval() on input.
  • Build Decimal and Fraction values from strings for exact results.

Exercise

A shop in Pune exports stock counts as text: ["12", " 7 ", "3.0", "", "twenty", "-4", "1_000"]. Write a function to_count(text) that returns a whole number of items, or None when the text is not a valid count. Accept "3.0" as 3, but reject negative numbers and values like "3.5". Print each input with its result.

Show solution
Python
def to_count(text):
    try:
        value = float(text)
    except ValueError:
        return None
    if value < 0 or not value.is_integer():
        return None
    return int(value)

for entry in ["12", " 7 ", "3.0", "", "twenty", "-4", "1_000", "3.5"]:
    print(repr(entry), "->", to_count(entry))
Output
'12' -> 12
' 7 ' -> 7
'3.0' -> 3
'' -> None
'twenty' -> None
'-4' -> None
'1_000' -> 1000
'3.5' -> None

float() accepts every valid form, including spaces and underscores, and ValueError catches the rest. is_integer() rejects 3.5, and int() turns the checked float into a whole number.

Quick Quiz

1. What does int(-9.99) return?

2. What is the type of 3 + 4.0?

3. What does bool("False") return?

4. Which is the safest way to turn user text into a number?

Learn Python with a mentor

Free lessons get you started. Our Python Programming training adds real projects and code reviews from working developers.

  • Project-based learning
  • Mentor code reviews
  • Free counselling call