Variables & Types
Dynamic typing, built-in types, type hints.
Python Variables & Types
Python is dynamically typed — variables don't have types, only values do. The same name can hold an int now, a string later, a list after that.
x = 5 # int
x = "hello" # str — no error
x = [1, 2, 3] # list — also fine
The type lives on the value at the right of =. The variable on the left is just a name pointing at it.
Built-in types
The everyday set:
| Type | Example | Notes |
|---|---|---|
int |
42, -7, 0 |
Arbitrary precision — 10**100 works. |
float |
3.14, 1.0e9 |
IEEE 754 doubles. 0.1 + 0.2 != 0.3. |
bool |
True, False |
Subclass of int: True == 1. |
str |
"hi", 'hi', """multi""" |
Immutable. |
bytes |
b"raw" |
Immutable. For binary data. |
list |
[1, 2, 3] |
Ordered, mutable. |
tuple |
(1, 2) |
Ordered, immutable. |
dict |
{"k": "v"} |
Ordered (since 3.7), mutable. |
set |
{1, 2, 3} |
Unordered, mutable, unique values. |
None |
None |
The unit / null value. |
Use type(x) to inspect and isinstance(x, T) to check.
Type hints (3.5+)
You can annotate types as a documentation + tooling aid. The runtime ignores them; type checkers (mypy, pyright) enforce them.
def greet(name: str, times: int = 1) -> str:
return ("Hello, " + name) * times
count: int = 0
users: list[str] = []
config: dict[str, str | int] = {"port": 8080}
name: str says "I expect a str here". Pass an int and Python won't complain at runtime — but mypy will.
Truthiness
Most things are truthy. The falsy values are:
False,None0,0.0,0j"",b"",(),[],{},set(),range(0)- Any object whose
__bool__()returnsFalseor__len__()returns0
So if items: is shorthand for "if the list isn't empty". Common idiom; not always what you want — if items is not None is the explicit version.
Numbers
Python integers are arbitrary precision:
2 ** 1000 # works fine
Floats are IEEE 754 doubles, so the usual gotchas apply:
0.1 + 0.2 # 0.30000000000000004
0.1 + 0.2 == 0.3 # False
For exact decimal arithmetic (money, scientific), use Decimal:
from decimal import Decimal
Decimal("0.1") + Decimal("0.2") # Decimal('0.3')
Strings
Strings are immutable sequences of Unicode code points. Three ways to create:
s = "double"
s = 'single'
s = """triple — preserves
newlines and "quotes" inside"""
f-strings are the modern formatting tool:
name, age = "Alice", 30
f"{name} is {age}" # "Alice is 30"
f"{age:>5}" # " 30" — right-align in 5 chars
f"{1/3:.4f}" # "0.3333"
f"{name=}" # "name='Alice'" — debug shorthand
Strings can't be mutated; s[0] = "X" raises. Use s.replace(...) and assign back.
None vs missing
None is Python's "no value" — explicit. It's NOT the same as a missing key in a dict; the dict key-check is key in d.
d = {"a": None}
"a" in d # True (key exists)
d["a"] is None # True (value is None)
Casting
Convert between types with the type names as functions:
int("42") # 42
float("3.14") # 3.14
str(42) # "42"
list("abc") # ["a", "b", "c"]
bool(0) # False
bool(0.0) # False
bool("") # False
bool([]) # False
int("abc") raises ValueError. int(3.7) truncates toward zero → 3.