Why I slowed down for the “easy” stuff
After weeks of SQL, switching back to Python felt like it should be a relief. It wasn’t, not at first. SQL rewards you for thinking in sets and tables. Python rewards you for thinking in steps, and I noticed I was reaching for SQL habits when a plain loop would have done the job.
So I went back to fundamentals on purpose: data structures, loops, functions, the built-ins everyone assumes you already know. Here’s what actually stuck.
Lists, dictionaries, sets: same job, different personality
I used to treat these as interchangeable containers. They’re not, and the difference only clicked once I thought about what each one is optimized to answer.
A List answers “what’s in position 3?” Order matters; duplicates are fine.
A dictionary answers “what’s the value for this key?” No searching, no scanning, just lookup.
A set answers “is this even in here?” Duplicates are impossible by design, and that’s the whole point.
Once I started picking a structure based on the question I was asking, instead of habit, my code got noticeably shorter.
Loops versus the built-ins that quietly replace them
The built-in functions were the real unlock this round:
lambda, sorted(), max(), and min().
sorted()in particular changed how I write loops. My instinct used to be: loop through the data, compare, track the winner manually. But:
sorted() leaves the original unchanged
top_student = max(students, key=lambda s: s["score"])
does in one line what used to take me four. The key argument was the piece I was missing conceptually — it’s not sorting the value itself; it’s sorting by a rule you hand it. Once that framing landed, sorted(), max(), and min() stopped being three things to memorize and became one idea applied three ways.
Functions: the point isn’t reuse, it’s naming
I always knew functions let you reuse code. What I hadn’t internalized is that a function is also a way of naming an idea. calculate_average(scores) tells the next reader (often me, a week later) what the block of code is for, not just what it does line by line.
That’s a small mental shift, but it changed how I structure even short scripts now. If a chunk of logic deserves a name, it deserves a function, even if I only call it once.
Running scripts from the terminal: the unglamorous skill
Not everything worth learning is conceptual. I also spent real time getting comfortable running' .pyfiles from the terminal instead of a notebook cell. Notebooks are forgiving in ways that hide mistakes; the terminal is not. Chasing down aNameError` because I ran cells out of order in a notebook, versus getting a clean traceback from a script, made me trust terminal output more.
It’s a small workflow change, but it’s the difference between “it works on my machine, in this order, right now” and “it works.”
What’s next
Fundamentals don’t feel exciting to write about, but they’re the layer everything else sits on. Next up, I want to take these same building blocks and put them back to work on a real dataset, the way SafariConnect did for SQL. Watch this space.😉😉😉
_
This is part of my ongoing series documenting the LuxDev Data Science, Data Analysis, and AI programme._


Top comments (0)