python · level 1

Variables & Types

Dynamic typing, built-in types, type hints.

100 XP

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, None
  • 0, 0.0, 0j
  • "", b"", (), [], {}, set(), range(0)
  • Any object whose __bool__() returns False or __len__() returns 0

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.