PythonData Types Overview

Data Types Overview

Every piece of data in Python — a number, a piece of text, a list of items, even a function — is an object with a type. The type determines what operations are allowed on the data and how it behaves. Python groups its built-in types into a few families: numeric, sequence, mapping, set, boolean, and a special “no value” type.

Everything Is an Object

Unlike languages that distinguish primitives from objects, Python treats everything as an object, including integers and booleans. That is why you can call methods directly on literals and why type() works uniformly across the language.

Python
print(type(42))          # <class 'int'>
print(type(3.14))        # <class 'float'>
print(type("hello"))     # <class 'str'>
print(type([1, 2, 3]))   # <class 'list'>
print(type(print))       # <class 'builtin_function_or_method'>

print((5).bit_length())  # 3  -- calling a method directly on an int literal
The Built-in Type Families

The table below summarizes Python’s core built-in types, an example literal for each, and whether values of that type can be changed in place (mutable) or not (immutable).

Category

Type

Example

Mutable?

Numeric

int

42

No

Numeric

float

3.14

No

Numeric

complex

3 + 4j

No

Sequence (text)

str

'hello'

No

Sequence

list

[1, 2, 3]

Yes

Sequence

tuple

(1, 2, 3)

No

Sequence

range

range(10)

No

Mapping

dict

{'a': 1}

Yes

Set

set

{1, 2, 3}

Yes

Set

frozenset

frozenset({1, 2})

No

Boolean

bool

True / False

No

Binary

bytes

b'data'

No

Binary

bytearray

bytearray(b'data')

Yes

None

NoneType

None

No

Note
Mutability matters a great deal in practice: mutable objects (lists, dicts, sets) can be changed in place, which affects how they behave as function arguments, dictionary keys, and in comparisons involving `is` versus `==`. Immutable objects (numbers, strings, tuples) can never be changed after creation — any “modification” actually creates a new object.
Numeric Types

Python has three built-in numeric types: int for whole numbers of arbitrary size, float for decimal numbers using double-precision, and complex for numbers with a real and imaginary part. These are explored in depth in the dedicated Numbers tutorial.

Python
whole = 42
decimal = 3.14159
imaginary = 2 + 3j

print(type(whole), type(decimal), type(imaginary))
# <class 'int'> <class 'float'> <class 'complex'>
Sequence Types

Sequences are ordered collections accessed by position (index). str, list, and tuple are the three you will use constantly. str holds text, list holds an ordered, mutable collection of any objects, and tuple holds an ordered, immutable collection.

Python
text = "hello"
items = [1, "two", 3.0]
point = (10, 20)

print(text[0], items[1], point[0])  # h two 10
Mapping Type: dict

A dict stores key-value pairs and looks values up by key rather than by numeric position. Keys must be hashable (so, typically, immutable types like strings, numbers, or tuples).

Python
user = {"name": "Ada", "age": 36}
print(user["name"])  # Ada
user["age"] = 37      # dicts are mutable
print(user)            # {'name': 'Ada', 'age': 37}
Set Types

set and frozenset store unordered collections of unique elements. Sets are useful for membership tests and removing duplicates; frozenset is the immutable variant, usable as a dict key or a member of another set.

Python
unique_numbers = {1, 2, 2, 3, 3, 3}
print(unique_numbers)  # {1, 2, 3}

locked = frozenset({1, 2, 3})
# locked.add(4)  # would raise AttributeError - frozensets are immutable
Boolean and None

bool has exactly two values, True and False, and is technically a subclass of int. NoneType has exactly one value, None, representing the absence of a value. Both get dedicated tutorials of their own.

type() vs isinstance()

type() returns the exact type of an object. isinstance() checks whether an object is an instance of a type or any of its subclasses, which is usually what you actually want when writing conditional logic.

Python
value = True

print(type(value) == bool)     # True
print(type(value) == int)      # False - type() is exact, and bool is not literally int
print(isinstance(value, int))  # True  - bool IS a subclass of int
print(isinstance(value, bool)) # True
Tip
Prefer `isinstance()` over `type() ==` in real code. It correctly handles inheritance and is the idiomatic way to check “is this object usable as a <type>?”
Binary Types (Briefly)

bytes and bytearray represent raw binary data — sequences of integers from 0 to 255 — used for things like file I/O, network protocols, and encoding text to a specific byte representation. You will encounter them more when working with files or networking, but it is worth knowing they exist alongside str.

Python
raw = b"hello"
print(type(raw))   # <class 'bytes'>
print(raw[0])       # 104 - the byte value of 'h'
Checking Everything at Once
  • int, float, complex — numbers

  • str, list, tuple, range — ordered sequences

  • dict — key-to-value mapping

  • set, frozenset — unordered unique collections

  • bool — True/False, a subtype of int

  • bytes, bytearray — raw binary data

  • NoneType — the type of None, representing "nothing"