Python is dynamically typed. Every value has a type, and types can be checked at runtime with type() or isinstance().

Numeric Types#

TypeDescriptionExample
intArbitrary precision integer42, -7, 0xFF, 0b1010
float64-bit floating-point3.14, 1e-5, float('inf')
complexComplex number3+4j, complex(3, 4)
boolBoolean (subclass of int)True, False
x: int = 42
y: float = 3.14
z: complex = 2 + 3j
b: bool = True

# int supports arbitrary precision
big = 10 ** 100

# Numeric literals
hex_val = 0xFF       # 255
bin_val = 0b1010     # 10
oct_val = 0o17       # 15
sep_val = 1_000_000  # underscores for readability

Sequence Types#

str#

Immutable sequence of Unicode characters.

s = "hello"
s = 'hello'
s = """multi
line"""

len(s)          # 5
s[0]            # 'h'
s[-1]           # 'o'
s[1:3]          # 'el'
s.upper()       # 'HELLO'

list#

Mutable, ordered sequence of any type.

fruits = ["apple", "banana", "cherry"]
mixed = [1, "hello", 3.14, True]

fruits.append("date")
fruits.insert(1, "avocado")
fruits.remove("banana")
fruits.pop()           # removes and returns last
fruits.pop(0)          # removes and returns at index
fruits.sort()
fruits.reverse()
len(fruits)
fruits[0]
fruits[-1]
fruits[1:3]

tuple#

Immutable, ordered sequence.

point = (1, 2)
single = (42,)           # single-element tuple needs trailing comma
empty = ()

x, y = point             # unpacking
a, *rest = (1, 2, 3, 4)  # starred unpacking: a=1, rest=[2,3,4]

range#

Lazy sequence of integers.

range(5)        # 0..4
range(2, 8)     # 2..7
range(0, 10, 2) # 0, 2, 4, 6, 8 (step)
list(range(5))  # [0, 1, 2, 3, 4]

Mapping Types#

dict#

Mutable mapping of unique keys to values. Ordered (insertion order) since Python 3.7.

person = {"name": "Alice", "age": 27}
person["city"] = "Vienna"
person.get("age")             # 27
person.get("email", "n/a")   # "n/a" (default if missing)
person.keys()
person.values()
person.items()               # dict_view of (key, value) pairs
"name" in person             # True
del person["city"]
person.pop("age")            # removes and returns value
person.update({"x": 1, "y": 2})

Set Types#

set#

Mutable, unordered collection of unique values. Supports set operations.

s = {1, 2, 3, 4}
s.add(5)
s.remove(3)        # raises KeyError if not found
s.discard(99)      # safe, no error if not found

a = {1, 2, 3}
b = {2, 3, 4}
a | b              # union: {1, 2, 3, 4}
a & b              # intersection: {2, 3}
a - b              # difference: {1}
a ^ b              # symmetric difference: {1, 4}
a.issubset(b)
a.issuperset(b)

frozenset#

Immutable set (hashable, can be used as dict key or set element).

fs = frozenset({1, 2, 3})

Boolean Type#

bool is a subclass of int. True == 1, False == 0.

True and False   # False
True or False    # True
not True         # False

# Falsy values: False, None, 0, 0.0, "", [], {}, set(), ()
bool(0)    # False
bool("")   # False
bool([])   # False
bool(1)    # True
bool("x")  # True

Binary Types#

b = b"hello"            # bytes: immutable sequence of bytes
ba = bytearray(b"hi")   # bytearray: mutable sequence of bytes
ba[0] = 65              # mutate in place
mv = memoryview(b)      # zero-copy view into bytes-like object

NoneType#

None is the sole instance of NoneType. Used to represent absence of a value.

x = None
x is None      # True (use `is`, not ==)

Type Checking and Conversion#

type(42)          # <class 'int'>
isinstance(42, int)        # True
isinstance(42, (int, float))  # True (checks multiple types)

# Conversions
int("42")         # 42
int(3.9)          # 3 (truncates)
float("3.14")     # 3.14
str(42)           # "42"
bool(0)           # False
list((1, 2, 3))   # [1, 2, 3]
tuple([1, 2, 3])  # (1, 2, 3)
set([1, 2, 2, 3]) # {1, 2, 3}
dict([("a", 1)])  # {"a": 1}

Mutability Summary#

TypeMutableOrderedUnique Keys/Elements
int, float, complex, boolNo--
strNoYes-
bytesNoYes-
tupleNoYes-
frozensetNoNoYes
listYesYesNo
bytearrayYesYes-
dictYesYes (insertion order)Keys unique
setYesNoYes

Troubleshooting#

IssueCauseSolution
TypeError: unhashable type: 'list'Lists cannot be dict keys or set elements because they are mutableUse a tuple instead of a list
(42,) vs (42) confusionParentheses without a trailing comma are just grouping, not a tupleAlways include a trailing comma for single-element tuples: (42,)
Modifying a list while iteratingDeleting or inserting during for loop skips elements or raises errorsIterate over a copy: for x in lst[:] or build a new list
{} creates a dict, not a setEmpty curly braces default to dictUse set() for an empty set
0.1 + 0.2 != 0.3Floating-point representation error (IEEE 754)Use math.isclose(0.1 + 0.2, 0.3) or the decimal module
Shallow copy surpriseslist.copy() and [:] only copy the top level; nested objects are sharedUse copy.deepcopy() for nested structures
is vs == for numbersSmall integers (-5 to 256) are cached, so is may work by accidentAlways use == for value comparison; reserve is for None

Sources#