asdict() converts a dataclass to a dict and recurses the whole way down, copying as it goes. That is usually what you want, and occasionally very much not.
The loop you are about to write is probably already in the standard library. islice, chain, pairwise and groupby cover most of them, and groupby has one rule you cannot skip.
A generator is an iterator you write as a plain function. It pauses at yield, resumes where it stopped, and never builds the list you were about to build.
A for loop is three steps you could write by hand. Once you have seen them, the empty-the-second-time bug stops being a surprise and becomes obvious.
Two builtins that replace the counter you keep writing by hand and the indexing you keep getting wrong. One of them also throws data away without telling you.
Every operator, every built-in, every piece of syntax in Python is a question asked of your object. The data model is the list of questions.
__slots__ removes the per-instance dict. It saves real memory at scale, catches typos for free, and is the wrong default.
Duck typing fails at the call site, long after the mistake. ABCs and Protocols both fix that, in opposite directions.
Four ways to hold structured data in Python. The deciding question is not style — it is whether a typo should fail loudly.
Every operator and built-in in Python is asking your object a question. Answer it and your class behaves like a native type.