Chapter 12, Basic
Type conversion and falsy values
Type conversion is routine. What often trips up beginners is not knowing what Python considers true or false.
Code for this chapter: basico/cap12_conversao_falsy.py
Explicit conversion
The functions int(), float(), str() and bool() convert explicitly. Two surprises: int() truncates towards zero, and round() rounds to the nearest even number when the value is exactly in the middle:
print(int("42") + 1)
print(float("3.5") * 2)
print(str(10) + " anos")
print(int(3.9), int(-3.9))
print(round(3.5), round(4.5), round(3.14159, 2))
43
7.0
10 anos
3 -3
4 4 3.14
When the text is not convertible, Python raises ValueError, and the message states exactly what the value was:
try:
int("abc")
except ValueError as erro:
print(erro)
invalid literal for int() with base 10: 'abc'
Implicit conversion
Python converts automatically when the calculation demands it, always to the "wider" type. The operator / is a special case: it always returns float, even when both ends are integers. For integer division use //:
print(1 + 2.5)
print(True + 1)
print(type(6 / 2), type(6 // 2))
3.5
2
<class 'float'> <class 'int'>
Falsy values
In a condition, Python converts the value with bool(). The rule is short: "empty" or "zero" values are false, and everything else is true. This is the complete list of those you encounter most often:
valores = [None, False, 0, 0.0, "", [], (), {}, set(), range(0)]
print([bool(v) for v in valores])
[False, False, False, False, False, False, False, False, False, False]
All yield False. Note that None is in the list, and it is the most frequent false in real code. These are true, and they surprise:
print(bool("0"), bool("False"), bool([0]), bool(" "))
True True True True
The string "0", a string "False", a list that contains zero and a string with space are all true because they are not empty.
Falsy is not the same as None
The language if not valor mixes "empty" with "zero" with "absent". When the distinction matters, compare with None explicitly:
def descricao(quantidade):
if quantidade is None:
return "não informado"
if not quantidade:
return "zero"
return f"{quantidade} unidades"
print(descricao(None))
print(descricao(0))
print(descricao(5))
não informado
zero
5 unidades
If I only wrote if not quantidade, None and 0 , they would fall into the same branch, and the system would treat "not informed" as "zero". In stock, this is a real bug.
Exercise 1
Numbers in Brazilian format
Write para_float(texto) that converts "12,5" into 12.5 and "1.234,56" into 1234.56.