Skip to content

enum Module Complexity

The enum module provides a way to define a set of symbolic names (members) bound to unique, constant values.

Complexity Reference

Operation Time Space Notes
Enum() class definition O(n) O(n) n = number of members
Access member by name O(1) O(1) Direct attribute lookup
Access member by value O(n) O(1) Linear search through members
Iteration for e in EnumClass O(n) O(1) n = number of members
len(EnumClass) O(1) O(1) Cached member count
name / value access O(1) O(1) Direct attribute

Enum Basics

Creating an Enum

from enum import Enum

# Define enum - O(n) for n members
class Color(Enum):
    RED = 1
    GREEN = 2
    BLUE = 3

# Access by name - O(1)
print(Color.RED)       # Color.RED
print(Color.RED.name)  # 'RED'
print(Color.RED.value) # 1

Member Access

from enum import Enum

class Status(Enum):
    PENDING = 'pending'
    ACTIVE = 'active'
    DONE = 'done'

# By name - O(1)
status = Status.ACTIVE      # Direct lookup
print(status.name)          # 'ACTIVE'

# By value - O(n)
status = Status('active')   # Must search all members
print(status.value)         # 'active'

Iteration

from enum import Enum

class Priority(Enum):
    LOW = 1
    MEDIUM = 2
    HIGH = 3

# Iterate all members - O(n)
for priority in Priority:
    print(f"{priority.name}: {priority.value}")

# Output:
# LOW: 1
# MEDIUM: 2
# HIGH: 3

Enum Types

IntEnum - Integer-like

from enum import IntEnum

# IntEnum allows comparison with integers - O(1)
class Code(IntEnum):
    OK = 200
    CREATED = 201
    BAD_REQUEST = 400
    NOT_FOUND = 404

# Compare with integers - O(1)
if Code.OK == 200:          # True
    print("Success")

if Code.NOT_FOUND > 400:    # True
    print("Client error")

# Can be used in arithmetic - O(1)
total = Code.OK + Code.CREATED  # 401

Flag - Bitwise Operations

from enum import Flag, auto

# Flag enum for combining values - O(1) per operation
class Permission(Flag):
    READ = auto()      # 1
    WRITE = auto()     # 2
    EXECUTE = auto()   # 4

# Combine flags - O(1)
user_perms = Permission.READ | Permission.WRITE

# Check flags - O(1)
if Permission.READ in user_perms:
    print("Can read")

if Permission.EXECUTE not in user_perms:
    print("Cannot execute")

# Remove flags - O(1)
user_perms = user_perms & ~Permission.WRITE

IntFlag - Integer Flag Combination

from enum import IntFlag, auto

class Status(IntFlag):
    READY = auto()        # 1
    WAITING = auto()      # 2
    ERROR = auto()        # 4

# Combine with | operator - O(1)
task_status = Status.READY | Status.WAITING

# Test with & operator - O(1)
if task_status & Status.READY:
    print("Task is ready")

# Convert from integer - O(n) for lookup
s = Status(3)  # Status.READY | Status.WAITING

Common Operations

Comparison

from enum import Enum

class Environment(Enum):
    DEV = 'development'
    PROD = 'production'

env = Environment.DEV

# Identity comparison - O(1)
if env is Environment.DEV:
    print("Development environment")

# Equality comparison - O(1)
if env == Environment.DEV:
    print("Using DEV")

# String comparison - O(1)
if env.value == 'development':
    print("Match by value")

Member Lookup

from enum import Enum

class Animal(Enum):
    DOG = 1
    CAT = 2
    BIRD = 3

# Get by name - O(1)
animal = Animal['DOG']          # Animal.DOG
print(animal.value)              # 1

# Get by value - O(n)
animal = Animal(2)               # Animal.CAT (searches all)

# Safe get by name - O(1)
try:
    animal = Animal['FISH']
except KeyError:
    print("Not found")

Check Membership

from enum import Enum

class Size(Enum):
    SMALL = 'S'
    MEDIUM = 'M'
    LARGE = 'L'

# Check by name - O(1)
if 'SMALL' in Size.__members__:
    print("Size.SMALL exists")

# Check by member - O(1)
if Size.SMALL in Size:
    print("SMALL is valid size")

# Get all names - O(n)
names = list(Size.__members__.keys())  # ['SMALL', 'MEDIUM', 'LARGE']

Advanced Patterns

Enum with Methods

from enum import Enum

class Status(Enum):
    PENDING = 'pending'
    PROCESSING = 'processing'
    DONE = 'done'

    # Method - O(1)
    def is_final(self):
        return self == Status.DONE

    # Method - O(1)
    def is_active(self):
        return self in (Status.PENDING, Status.PROCESSING)

# Use methods - O(1)
status = Status.PROCESSING
if status.is_active():
    print("Task is running")

Enum Aliases

from enum import Enum

class Color(Enum):
    RED = 1
    CRIMSON = 1      # Alias for RED
    GREEN = 2
    BLUE = 3

# All refer to same member - O(1)
print(Color.RED is Color.CRIMSON)  # True
print(len(Color))                  # 3 (aliases don't count)

Functional API

from enum import Enum

# Create enum from list - O(n)
Animal = Enum('Animal', 'DOG CAT BIRD')
# Equivalent to:
# class Animal(Enum):
#     DOG = 1
#     CAT = 2
#     BIRD = 3

# Access - O(1)
print(Animal.DOG)      # Animal.DOG
print(Animal.DOG.value) # 1

Custom Value Processing

from enum import Enum

class HttpStatus(Enum):
    OK = (200, 'OK')
    CREATED = (201, 'Created')
    BAD_REQUEST = (400, 'Bad Request')

    def __init__(self, code, message):
        self.code = code
        self.message = message

    # O(1)
    def __str__(self):
        return f"{self.code} {self.message}"

# Access - O(1)
status = HttpStatus.OK
print(status.code)      # 200
print(status.message)   # 'OK'
print(str(status))      # '200 OK'

Performance Comparison

Access Methods

from enum import Enum

class Day(Enum):
    MONDAY = 1
    TUESDAY = 2
    WEDNESDAY = 3
    THURSDAY = 4
    FRIDAY = 5
    SATURDAY = 6
    SUNDAY = 7

# By name - O(1), fastest
day = Day.MONDAY

# By name with getattr - O(1)
day = getattr(Day, 'MONDAY')

# By name dict - O(1)
day = Day.__members__['MONDAY']

# By value - O(n), iterates all members
day = Day(1)

Iteration vs Lookup

from enum import Enum

class Status(Enum):
    PENDING = 'pending'
    ACTIVE = 'active'
    DONE = 'done'

# Get all - O(n)
all_statuses = list(Status)  # 3 operations

# Get one by name - O(1)
status = Status.PENDING

# Get one by value - O(n)
status = Status('pending')   # Must search

When to Use Enum

Good For

  • Fixed set of named constants
  • Type safety (prevents invalid values)
  • Better readability than magic numbers/strings
  • Clear intent and documentation
from enum import Enum

# Good: Type-safe status
class OrderStatus(Enum):
    PENDING = 'pending'
    SHIPPED = 'shipped'
    DELIVERED = 'delivered'

def process_order(status: OrderStatus) -> None:
    if status == OrderStatus.PENDING:
        send_to_warehouse()

Avoid When

  • Set changes frequently
  • Need dynamic values
  • Simple flags where tuples work
  • Performance-critical lookup by value
from enum import Enum

# Avoid: Frequent changes needed
# Use dict or database instead
STATUSES = {1: 'pending', 2: 'active'}  # Easier to modify

Memory Efficiency

Enum Instance Caching

from enum import Enum

class Color(Enum):
    RED = 1
    GREEN = 2
    BLUE = 3

# All references same instance - O(1) memory per unique value
color1 = Color.RED
color2 = Color.RED
color3 = Color.RED

print(id(color1) == id(color2) == id(color3))  # True

Small Memory Footprint

from enum import Enum
import sys

class Status(Enum):
    OK = 1
    ERROR = 2

# Enum members are cached singletons
status = Status.OK
print(sys.getsizeof(status))  # Very small, reused instance