I want to start this week with a question. You finished the Advanced track. You shipped the async pipeline. You write decorators and generators without blinking. Why do you think your PRs still come back with comments about style?
Honestly? I assumed style comments were cosmetic. Spaces, naming, formatting. Things that do not affect whether the code runs. I fixed them because reviewers asked, not because I thought they mattered.
That assumption is the gap we are closing this week. The comments you got — "not Pythonic," "use EAFP," "why are you doing LBYL here" — are not about formatting. They are about a different way of reasoning about code. Python has idioms: patterns so common and well-understood that experienced developers read them as single units of meaning, the way you read a word instead of spelling out each letter. When your code does not use those idioms, it takes longer to read and signals that the author does not know the culture, even if they know the language.
But there is no formal definition of "Pythonic." I Googled it. The results are either import this or trivial examples. How is it something you can teach?
You are right that there is no spec. But the idioms are real and they are learnable. This week I am going to show you five specific patterns your code does not use yet: EAFP versus LBYL, truthiness and short-circuit evaluation, the walrus operator and assignment expressions, star unpacking and the dict merge operator, and enumeration patterns. For each one I will show you a before and after — your working code next to what a senior dev would write — and I will explain why the after version is preferred. Not preferred as in "tastes better." Preferred as in: shorter, clearer, faster, or safer.
The EAFP thing specifically. Twelve comments all said the same phrase. That is the one I most want to understand. I have been checking keys before accessing them since I started writing Python. Arjun rewrote every one of those checks. What is he seeing that I am missing?
He is seeing the tax you are paying to bring a Java habit into Python. You learned defensive programming: check before you act. It is sound engineering in most contexts. Python inverted it. That inversion is not arbitrary — it comes out of how Python implements dictionary lookups and exceptions at the interpreter level. Once you see the cost model, you will not go back. And once you know EAFP, the other idioms this week will start to feel like the same insight applied to different situations. Pythonic code is not a checklist of tricks. It is a consistent way of writing what you mean in the fewest possible tokens.
The word Pythonic appears in thousands of code reviews and almost never gets defined precisely. That vagueness is part of why developers who know Python well still feel like they are missing something when reviewers use the term. This essay is an attempt at a precise definition.
Pythonic code is code that uses the language's preferred patterns instead of workarounds for the absence of those patterns. Every language has constructs that solve common problems directly, and workarounds developers use when they do not know those constructs exist. Pythonic code uses the constructs. Non-Pythonic code uses the workarounds — correctly, completely, but in a way that signals the author imported a solution from a different context.
The clearest example is the EAFP versus LBYL distinction. Python developers write try/except around dictionary access because Python's exception machinery is fast and because Python's glossary explicitly endorses the pattern. Developers who learned their defaults in C, Java, or JavaScript write if key in d: value = d[key] — a LBYL check that works, but that pays the cost of two dictionary lookups instead of one and signals that the author's mental model came from a language where exceptions are expensive. The code is not wrong. It is not idiomatic.
This distinction matters because idiomatic code carries less cognitive weight for experienced readers. When a senior Python developer reads config.get('timeout', 30), they parse it as a unit: "get timeout, default thirty." When they read if 'timeout' in config: timeout = config['timeout'] else: timeout = 30, they have to trace the logic step by step. The outcome is the same. The reading experience is not. At scale, across a codebase, the accumulated weight of non-idiomatic patterns makes code harder to maintain and slower to review.
The five idioms in this week are not arbitrary selections from a list of Python features. They are the patterns that appear most often in code reviews of developers who know the language but not the culture: EAFP for access patterns, truthiness for conditional expressions, walrus for assignment-within-expression, unpacking for sequence manipulation, and iteration idioms for loop patterns. Each one has a direct non-idiomatic equivalent that works correctly. The idiomatic version is shorter, clearer, and usually faster. Learning them is not about memorizing syntax. It is about changing the way you reach for solutions — from "how do I make this work" to "what does Python give me for exactly this problem."
Sign up to save your notes.
I want to start this week with a question. You finished the Advanced track. You shipped the async pipeline. You write decorators and generators without blinking. Why do you think your PRs still come back with comments about style?
Honestly? I assumed style comments were cosmetic. Spaces, naming, formatting. Things that do not affect whether the code runs. I fixed them because reviewers asked, not because I thought they mattered.
That assumption is the gap we are closing this week. The comments you got — "not Pythonic," "use EAFP," "why are you doing LBYL here" — are not about formatting. They are about a different way of reasoning about code. Python has idioms: patterns so common and well-understood that experienced developers read them as single units of meaning, the way you read a word instead of spelling out each letter. When your code does not use those idioms, it takes longer to read and signals that the author does not know the culture, even if they know the language.
But there is no formal definition of "Pythonic." I Googled it. The results are either import this or trivial examples. How is it something you can teach?
You are right that there is no spec. But the idioms are real and they are learnable. This week I am going to show you five specific patterns your code does not use yet: EAFP versus LBYL, truthiness and short-circuit evaluation, the walrus operator and assignment expressions, star unpacking and the dict merge operator, and enumeration patterns. For each one I will show you a before and after — your working code next to what a senior dev would write — and I will explain why the after version is preferred. Not preferred as in "tastes better." Preferred as in: shorter, clearer, faster, or safer.
The EAFP thing specifically. Twelve comments all said the same phrase. That is the one I most want to understand. I have been checking keys before accessing them since I started writing Python. Arjun rewrote every one of those checks. What is he seeing that I am missing?
He is seeing the tax you are paying to bring a Java habit into Python. You learned defensive programming: check before you act. It is sound engineering in most contexts. Python inverted it. That inversion is not arbitrary — it comes out of how Python implements dictionary lookups and exceptions at the interpreter level. Once you see the cost model, you will not go back. And once you know EAFP, the other idioms this week will start to feel like the same insight applied to different situations. Pythonic code is not a checklist of tricks. It is a consistent way of writing what you mean in the fewest possible tokens.
The word Pythonic appears in thousands of code reviews and almost never gets defined precisely. That vagueness is part of why developers who know Python well still feel like they are missing something when reviewers use the term. This essay is an attempt at a precise definition.
Pythonic code is code that uses the language's preferred patterns instead of workarounds for the absence of those patterns. Every language has constructs that solve common problems directly, and workarounds developers use when they do not know those constructs exist. Pythonic code uses the constructs. Non-Pythonic code uses the workarounds — correctly, completely, but in a way that signals the author imported a solution from a different context.
The clearest example is the EAFP versus LBYL distinction. Python developers write try/except around dictionary access because Python's exception machinery is fast and because Python's glossary explicitly endorses the pattern. Developers who learned their defaults in C, Java, or JavaScript write if key in d: value = d[key] — a LBYL check that works, but that pays the cost of two dictionary lookups instead of one and signals that the author's mental model came from a language where exceptions are expensive. The code is not wrong. It is not idiomatic.
This distinction matters because idiomatic code carries less cognitive weight for experienced readers. When a senior Python developer reads config.get('timeout', 30), they parse it as a unit: "get timeout, default thirty." When they read if 'timeout' in config: timeout = config['timeout'] else: timeout = 30, they have to trace the logic step by step. The outcome is the same. The reading experience is not. At scale, across a codebase, the accumulated weight of non-idiomatic patterns makes code harder to maintain and slower to review.
The five idioms in this week are not arbitrary selections from a list of Python features. They are the patterns that appear most often in code reviews of developers who know the language but not the culture: EAFP for access patterns, truthiness for conditional expressions, walrus for assignment-within-expression, unpacking for sequence manipulation, and iteration idioms for loop patterns. Each one has a direct non-idiomatic equivalent that works correctly. The idiomatic version is shorter, clearer, and usually faster. Learning them is not about memorizing syntax. It is about changing the way you reach for solutions — from "how do I make this work" to "what does Python give me for exactly this problem."