Type Conversions

Concepts covered: Type Conversion

Every value in Python has exactly one type, and the operators act according to that type. 19 + 99 adds 2 numbers and gives 118, while "19" + "99" joins 2 strings and gives "1999". Text is how data arrives from a keyboard, a web form or a spreadsheet export, so a program that wants arithmetic has to convert first.

price_text = "4.25"
quantity_text = "4"
print(price_text * 4)
price = float(price_text)
quantity = int(quantity_text)
print(price * quantity)
print(type(price).__name__, type(quantity).__name__)

Output:

4.254.254.254.25
17.0
float int

The first print repeats the text 4 times, because * on a string means repeat. After float() and int() turn the text into numbers, the same * multiplies. The product shows as 17.0 because any arithmetic that involves a float produces a float, even when the result is a whole number.

The 3 converters you will use most

CallResultWhat happened
`int("42")``42`digits parsed as a whole number
`int(7.9)``7`fraction dropped toward zero
`int(-7.9)``-7`still toward zero, so -7 and never -8
`int(True)``1`True counts as 1, False as 0
`float("2.5")``2.5`text parsed as a decimal
`float(3)``3.0`whole number widened to a float
`float("1e3")``1000.0`scientific notation accepted
`str(42)``"42"`number written out as text
`str(3.0)``"3.0"`the decimal point survives

int() on a float never rounds. int(7.9) gives 7 and int(7.1) gives 7, because the conversion keeps the whole part and discards the rest. When you need the nearest whole number, that's a different operation, and this lesson leaves it alone: the point here is that int() only ever removes.

Conversions that lose data

A conversion is a one way trip whenever the target type cannot hold everything the source held. int(7.9) throws away the .9, and converting back with float() gives 7.0. Text has the same problem in the other direction: a number has no leading zeros, so a US postal code that starts with 0 loses a digit the moment it becomes an int.

zip_code = "02134"
as_number = int(zip_code)
print(as_number)
print(str(as_number))
print(str(as_number) == zip_code)

Output:

2134
2134
False

The code round trips as "2134", which a shipping label would reject. Postal codes, phone numbers and account identifiers are made of digits, but you never add or multiply them, so keep them as str. Convert to a number only when the value is about to be used as one.

StartConvertConvert backWhat was lost
`7.9``int()` gives `7``float()` gives `7.0`the fraction
`"02134"``int()` gives `2134``str()` gives `"2134"`the leading zero
`42``str()` gives `"42"``int()` gives `42`nothing
`3.0``int()` gives `3``float()` gives `3.0`nothing

int() refuses a decimal point

reading = "42.5"
print(float(reading))
print(int(float(reading)))

Output:

42.5
42

int() reads a string as a whole number and refuses anything else, including a decimal point: int(reading) on this text stops with ValueError: invalid literal for int() with base 10: '42.5'. The fix takes 2 steps: int(float(reading)) parses the decimal first and then drops the fraction, giving the 42 on the last line. The ValueError quotes the exact text it rejected, so the traceback shows what the string really contained, which matters when the culprit is a stray space or a currency symbol you didn't know was there.

Converting the other way for display

items = 3
print("You have " + str(items) + " items")
print("You have", items, "items")

Output:

You have 3 items
You have 3 items

Writing "You have " + items without the conversion stops with TypeError: can only concatenate str (not "int") to str, because + needs both operands to be strings before it will concatenate. str(items) produces "3", which joins without complaint. print() with several arguments separated by commas converts each one for you, as line 3 shows, so it needs no str() call; the explicit conversion is for the moment you build one string to keep.

What does this program print?

count = "12"
total = int(count) + 3
print(str(total) + " items")

Each converter matches the shape of the text it reads: float() for text with a decimal point, int() for whole digits. Handing "12.5" to int() would stop with the ValueError from earlier, and once both values are numbers, a float times an int gives a float.

About this lesson

This section is part of the Python Expressions: Intermediate lesson on DataDriven, the home of data engineering. Lessons cover SQL, Python, Spark, data modeling and pipeline architecture, and each section pairs its explanation with worked examples and practice you run as you go.