03open 25 min

Data and state modeling: lists, dicts, classes, and dataclasses instead of struct-first design

Learn when Python wants a list, dict, class, or dataclass rather than a translated Go struct-heavy model.

by the end of this lesson you can

  • Chooses dict, class, or dataclass for a reason
  • Keeps the result easy to read in Python
  • Avoids defaulting to struct-like design just from habit

Overview

Go developers often begin with structs because they are the obvious center of many designs. Python gives you more flexibility up front. Sometimes a dict is enough, sometimes a dataclass is the cleanest fit, and sometimes a small class is useful. The skill is choosing the lightest model that still makes the code understandable.

In Go, you often

start by defining structs and then build functions or methods around those explicit shapes.

In Python, the common pattern is

to choose among dicts, lists, classes, and dataclasses based on readability and the amount of structure the problem actually needs.

why this difference matters

This is a major friction point for Go developers because Python's flexibility can feel underspecified until you learn what kinds of lightweight structure are considered normal.

Go

type User struct {
    Name  string
    Admin bool
}

Python

from dataclasses import dataclass

@dataclass
class User:
    name: str
    is_admin: bool = False

Deeper comparison

Go version

type Job struct {
    ID     string
    Status string
}

jobs := []Job{{ID: "1", Status: "queued"}}

Python version

jobs = [
    {"id": "1", "status": "queued"}
]

Reflect

How do you decide when Python should keep a shape lightweight and when it should introduce a dataclass or class?

what a strong answer notices

A strong answer mentions readability, repeated use, invariants, and whether explicit named fields improve the code more than a flexible dict would.

Rewrite

Rewrite this Go struct-based example into Python and choose the data shape intentionally.

Rewrite this Go

type Config struct {
    Region string
    Debug  bool
}

what good looks like

  • Chooses dict, class, or dataclass for a reason
  • Keeps the result easy to read in Python
  • Avoids defaulting to struct-like design just from habit

Practice

Design a Python representation for records processed by a background job, and explain where a dict is enough versus where a dataclass helps.

success criteria

  • Uses Python's flexible modeling tools intentionally
  • Explains tradeoffs between lighter and more explicit shapes
  • Keeps the model readable to a Python developer

Common mistakes

  • Rebuilding every Python data shape around translated Go structs.
  • Treating dicts as automatically sloppy instead of sometimes being the clearest tool.
  • Adding classes before the code has enough behavior or structure to justify them.

takeaways

  • This is a major friction point for Go developers because Python's flexibility can feel underspecified until you learn what kinds of lightweight structure are considered normal.
  • A strong answer mentions readability, repeated use, invariants, and whether explicit named fields improve the code more than a flexible dict would.
  • Uses Python's flexible modeling tools intentionally