Type Casting & Conversion
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:
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]))42 -7 100000 9 -9 -10 12.5 1000.0 -0.25 3.0 True None [1, 2]
What to notice:
int()andfloat()ignore spaces and new lines around the text, accept a+or-sign, and accept underscores between digits, so the lakh grouping1_00_000works.int()on a float cuts towards zero:9.99becomes9and-9.99becomes-9. If you want the nearest whole number, useround().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.
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)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.
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"))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.
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))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".
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))'₹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.
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))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. Usefloat(), orint(float(text))if you really want to drop the decimals. - Expecting
bool("False")to beFalse. Any non-empty string is true. Compare the text instead. - Forgetting to convert back.
"Total: " + 450fails. Use an f-string:f"Total: {450}". - Checking with
isdigit()instead oftry. It rejects negative numbers and accepts characters thatint()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()andbool()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, sobool("False")isTrue.- Parse messy text by cleaning it and catching
ValueError; never useeval()on input. - Build
DecimalandFractionvalues 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
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))'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?
int() cuts towards zero, so the decimal part is simply dropped.
2. What is the type of 3 + 4.0?
Mixing an int and a float promotes the result to float.
3. What does bool("False") return?
Any non-empty string is truthy, whatever words it contains.
4. Which is the safest way to turn user text into a number?
The try block asks the real converter and handles every bad case, including ones isdigit() gets wrong.
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
