Python Data Types — The Complete Guide for 2026
Advertisement
Introduction
Why This Matters
Every piece of data in Python is an object with a type, and choosing the right type is fundamental to writing correct, efficient code. Python's dynamic typing makes it flexible, but that flexibility comes with responsibility. Misusing types is a leading cause of runtime errors, performance bottlenecks, and subtle bugs.
Understanding Python's type system also unlocks advanced features like type hints, Pydantic validation, dataclasses, and mypy static analysis — all of which are widely used in production Django, FastAPI, and data science codebases. Type awareness is also heavily tested in Python technical interviews.
This guide covers every built-in data type with practical examples, mutability rules, and when to choose one type over another.
Numeric Types: int, float, complex
# int: arbitrary precision
age = 25
large = 10 ** 100 # Python handles big integers natively
# float: IEEE 754 double precision
price = 19.99
pi = 3.14159
# float precision gotcha
print(0.1 + 0.2) # 0.30000000000000004
from decimal import Decimal
print(Decimal("0.1") + Decimal("0.2")) # 0.3 (exact)
# complex
z = 3 + 4j
print(z.real, z.imag) # 3.0 4.0Strings
Strings are immutable sequences of Unicode characters.
name = "Alice"
greeting = f"Hello, {name}!" # f-string (Python 3.6+)
# Common methods
print(" hello ".strip()) # 'hello'
print("hello".upper()) # 'HELLO'
print("a,b,c".split(",")) # ['a', 'b', 'c']
print("-".join(["a", "b", "c"])) # 'a-b-c'
print("hello world".replace("world", "Python")) # 'hello Python'
# Multi-line string
message = """
Dear user,
Welcome to our platform.
"""Boolean
bool is a subclass of int — True == 1 and False == 0.
is_active = True
is_deleted = False
print(True + True) # 2
print(bool(0)) # False
print(bool("")) # False
print(bool([])) # False
print(bool(None)) # False
print(bool("0")) # True — non-empty stringList — Mutable Ordered Sequence
fruits = ["apple", "banana", "cherry"]
fruits.append("date")
fruits.insert(1, "avocado")
fruits.remove("banana")
fruits.sort()
print(fruits[0]) # first element
print(fruits[-1]) # last element
print(fruits[1:3]) # slice
# List is mutable
fruits[0] = "apricot"Tuple — Immutable Ordered Sequence
coordinates = (40.7128, -74.0060)
rgb = (255, 128, 0)
# Unpacking
lat, lon = coordinates
print(f"Lat: {lat}, Lon: {lon}")
# Tuples as dict keys (lists cannot be keys)
location_map = {(40.7128, -74.0060): "New York"}
# Named tuple for readability
from collections import namedtuple
Point = namedtuple("Point", ["x", "y"])
p = Point(3, 4)
print(p.x, p.y) # 3 4Dictionary — Mutable Key-Value Map
user = {
"id": 1,
"name": "Alice",
"email": "alice@example.com",
}
# Access
print(user["name"])
print(user.get("phone", "N/A")) # safe access with default
# Mutate
user["age"] = 30
user.update({"email": "new@example.com", "active": True})
# Iterate
for key, value in user.items():
print(f"{key}: {value}")
# Dict comprehension
squared = {x: x**2 for x in range(5)}Set — Mutable Unordered Unique Collection
tags = {"python", "web", "api", "python"} # duplicates removed
print(tags) # {'python', 'web', 'api'}
tags.add("fastapi")
tags.discard("web") # no error if not present
# Set operations
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}
print(a | b) # union: {1, 2, 3, 4, 5, 6}
print(a & b) # intersection: {3, 4}
print(a - b) # difference: {1, 2}None
None is Python's null value — a singleton of NoneType.
result = None
if result is None: # use 'is', not '=='
print("No result yet")
def find_user(id: int):
# Returns None implicitly if not found
passType Checking and Conversion
print(type(42)) # <class 'int'>
print(isinstance(42, int)) # True
print(isinstance(42, (int, float))) # True
# Conversion
int("42") # 42
float("3.14") # 3.14
str(100) # '100'
list((1,2,3)) # [1, 2, 3]
set([1,1,2]) # {1, 2}Common Mistakes
- Using mutable defaults in function signatures:
def f(items=[])— useNoneinstead - Comparing to
Nonewith==instead ofis - Confusing shallow copy with deep copy for nested structures
- Using a list where a set is more appropriate for membership checks
- Assuming dict ordering in Python 2 — in Python 3.7+, dicts maintain insertion order
Best Practices
- Use type hints to document expected types:
def greet(name: str) -> str - Prefer tuples for fixed-size records that should not change
- Use
dataclassesor PydanticBaseModelfor structured data in APIs - Use
frozensetwhen you need a hashable, immutable set - Use
collections.defaultdictor.get()to avoidKeyErrorin dicts
Key Takeaways
- Python has 8 core built-in types: int, float, complex, str, bool, list, tuple, dict, set
- Mutable types (list, dict, set) can be changed in place; immutable types (str, tuple, int) cannot
Noneis Python's null value and should be compared withis, not==- Dicts in Python 3.7+ maintain insertion order
- Sets are ideal for deduplication and fast membership testing (O(1) lookup)
- Use
isinstance()for type checking, nottype() == - Type hints + mypy or Pyright add static type safety to dynamic Python code
Advertisement