MOD-04 · Sequence #4 · Python Basics

Python Data Types

Python is dynamically typed and strongly typed. Every entity in Python is an instance of a type inheriting from object. Knowing primitive scalar types versus composite sequence and mapping collections is essential.

Live Interactive Code Snippet (Python 3.12 CPython WASM) Open in Practice Mode →
x = 5
print(type(x))  # <class 'int'>
y = "Python"
print(type(y))  # <class 'str'>

Core Principles & Mental Models

1. Dynamic Typing vs. Strong Typing

Type Checking at Runtime without Implicit Coercion

  • Dynamic typing means variables do not have fixed types; values have types. A variable can hold an int and later hold a str.
  • Strong typing means Python will not implicitly cast incompatible types. Adding "5" + 5 raises a TypeError rather than performing string concatenation.
x = 42
print(type(x))  # <class 'int'>
x = "University"
print(type(x))  # <class 'str'>
# print("Score: " + 100) -> Raises TypeError!
💡 Key Takeaway: Dynamic typing allows rapid reassignment, while strong typing prevents subtle silent type coercion bugs.

2. The Taxonomy of Built-in Python Types

Scalars, Sequences, Sets, and Mappings

  • Numeric: int (arbitrary precision), float (IEEE 754 double), complex.
  • Sequence: list (mutable), tuple (immutable), range (lazy sequence), str (immutable unicode).
  • Set: set (mutable, unique), frozenset (immutable, unique).
  • Mapping: dict (key-value hash table).
  • Boolean & Null: bool (subclass of int), NoneType (singleton None).
types_demo = [
    (10, type(10)),
    (3.14, type(3.14)),
    ("text", type("text")),
    ([1, 2], type([1, 2])),
    ((1, 2), type((1, 2))),
    ({"key": "val"}, type({"key": "val"})),
    ({1, 2}, type({1, 2})),
    (None, type(None))
]
for val, t in types_demo:
    print(f"{repr(val):<16} -> {t.__name__}")
💡 Key Takeaway: Every built-in type corresponds to a first-class CPython class object.

Interactive Walkthrough Examples

Type Inspection with type() and isinstance() (Basic)

Comparing type() equality versus isinstance() polymorphism.

val = True
print("type(val) is int?", type(val) is int)  # False: type is bool
print("isinstance(val, int)?", isinstance(val, int))  # True: bool subclasses int!
print("isinstance(val, (int, float))?", isinstance(val, (int, float)))

Explanation: In Python, bool is actually a subclass of int (True == 1, False == 0). Use isinstance() for robust type checks.

Common Misconceptions & Exam Traps

Common Pitfall: Using type(x) == T Instead of isinstance(x, T)

type(x) == int does not respect inheritance hierarchies, whereas isinstance() correctly supports polymorphic subclasses.

Buggy Code
def check(x):
    if type(x) == int:
        return "Integer"
# Fails for subclasses like boolean or custom subclasses!
Correct Solution
def check(x):
    if isinstance(x, int):
        return "Integer"

Exam Trap Note: Exam questions frequently test why `type(True) == int` is False while `isinstance(True, int)` is True.

Conceptual Knowledge Self-Check Quiz

Q1: Which of the following built-in types in Python is mutable?

  1. tuple
  2. str
  3. frozenset
  4. list

Lists are mutable sequences. Tuples, strings, and frozensets cannot be modified in place after creation.

Algorithmic Practice Challenges

Idiomatic Best Practices

  • ✅ Prefer isinstance(obj, classinfo) over direct type equality checks.
  • ✅ Use Python 3.10+ type hints (e.g. def func(x: int | str) -> bool) to document function signatures.

All 26 Curriculum Modules