Variables and Data Types

Variable Assignment

Python is dynamically typed: a variable’s type is determined at runtime and can change.

x = 10          # x is an int
x = "hello"     # now x is a str, perfectly legal

Variables are names bound to objects, not boxes holding values. This distinction matters for mutability, see the note on mutable default arguments in Common-Pitfalls.

a = [1, 2, 3]
b = a          # b points to the SAME list object as a
b.append(4)
print(a)       # [1, 2, 3, 4]  now a changed too

Multiple Assignment

x, y, z = 1, 2, 3
a = b = c = 0            # all three point to the same int object (ints are immutable so this is safe)
x, y = y, x               # classic swap, no temp variable needed
first, *rest = [1, 2, 3, 4]   # first = 1, rest = [2, 3, 4]

Core Built-in Types

TypeExampleMutable?Notes
int42NoArbitrary precision, no overflow
float3.14NoDouble precision (64-bit)
complex2 + 3jNoRarely used outside scientific code
boolTrue, FalseNoSubclass of int (True == 1)
str"hi"NoSequence of Unicode characters
list[1, 2]YesOrdered, allows duplicates
tuple(1, 2)NoOrdered, immutable
dict{"a": 1}YesKey value mapping, insertion ordered since 3.7
set{1, 2}YesUnordered, unique elements
frozensetfrozenset({1,2})NoImmutable set
NoneTypeNoneN/ARepresents absence of a value

Checking Types

x = 42
type(x)                  # <class 'int'>
isinstance(x, int)       # True, preferred over type() == comparisons
isinstance(x, (int, float))  # True if either type matches

isinstance over type() ==

isinstance() respects inheritance, so it correctly handles subclasses. Direct type(x) == int comparisons break polymorphism.

Dynamic Typing vs Duck Typing

Python does not care about an object’s declared type, only what it can do (if it walks like a duck and quacks like a duck).

def describe(item):
    print(item.upper())  # works for anything with an .upper() method
 
describe("hello")   # works, str has .upper()

None and Truthiness

None is Python’s null value, a singleton object of NoneType.

x = None
x is None       # True, always use 'is' not '==' for None checks

is vs ==

== checks value equality, is checks object identity. Always use is None or is not None, never == None.

Falsy Values

The following are all considered False in a boolean context:

bool(None)      # False
bool(0)         # False
bool(0.0)       # False
bool("")        # False
bool([])        # False
bool({})        # False
bool(set())     # False
bool(())        # False

Everything else is truthy, including non-empty strings, non-zero numbers, and non-empty collections.

Constants

Python has no true constants, only convention. Uppercase names signal “do not reassign this.”

MAX_RETRIES = 5
PI = 3.14159

For enforced immutability, use typing.Final (see Type-Hints-and-Typing) or an Enum (see Standard-Library-Highlights).