15 Python Tricks Every Beginner Wishes They Knew Earlier

Python API Experiments - My Code Diary

15 Python Tricks Every Beginner Wishes They Knew Earlier

I remember the exact moment I realized I had been writing Python the hard way.

It was a Tuesday night. I had been staring at 200 lines of code that took 40 minutes to run. A senior dev leaned over, looked at my screen for about three seconds, and rewrote the core logic in six lines. It ran in under two.

I didn’t sleep well that night — not because I was embarrassed, but because I kept thinking: how many other things do I not know that I don’t know?

That question sent me down a four-year rabbit hole of Python internals, community projects, open-source codebases, and a lot of late nights with the docs. What follows are 15 tricks I wish someone had handed me as a printout on day one. Not the tricks you find in “Python in 10 Minutes” videos. The real ones. The ones that quietly separate good code from great code.


1. You Do Not Need a Loop to Flatten a List

Every beginner reaches for a nested loop when they see a list of lists. There is a cleaner path.

nested = [[1, 2], [3, 4], [5, 6]]
flat = [x for sublist in nested for x in sublist]
print(flat)  # [1, 2, 3, 4, 5, 6]

This is a list comprehension with two for clauses. Read it like English: “give me x, for each sublist in nested, for each x in sublist.” Once this clicks, you will use it constantly.


2. enumerate() Exists for a Reason — Use It

Manually managing an index counter is one of the most common beginner habits. Python already solved this.

languages = ["Python", "Rust", "Go"]

for index, lang in enumerate(languages, start=1):
    print(f"{index}. {lang}")

The start=1 argument is the part most people miss. You do not have to start at zero.


3. Swap Variables Without a Temp Variable

This one is genuinely Pythonic and shows up in real interviews.

a, b = 10, 20
a, b = b, a
print(a, b)  # 20 10

Python evaluates the right side fully before assigning. No temp variable, no confusion, no ceremony.


4. Dictionary .get() Is Not Optional — It Is the Standard

Accessing a dictionary key that might not exist will raise a KeyError. The .get() method gives you a graceful fallback instead.

user = {"name": "Ali", "age": 25}
city = user.get("city", "Unknown")
print(city)  # Unknown

This single habit will eliminate a category of runtime bugs from your code permanently.


5. collections.defaultdict for Grouping Without Guard Clauses

The standard pattern for grouping items into a dictionary involves checking whether a key exists before appending. defaultdict removes that entirely.

from collections import defaultdict

words = ["apple", "ant", "banana", "bear", "cherry"]
grouped = defaultdict(list)

for word in words:
    grouped[word[0]].append(word)

print(dict(grouped))
# {'a': ['apple', 'ant'], 'b': ['banana', 'bear'], 'c': ['cherry']}

Less code. Same result. No if-else guarding required.


6. zip() Lets You Walk Two Lists in Lockstep

If you have ever written for i in range(len(list1)) just to access list2[i] at the same time, this is for you.

names = ["Sara", "Ahmed", "Zara"]
scores = [88, 95, 79]

for name, score in zip(names, scores):
    print(f"{name}: {score}")

Pro Tip: zip() stops at the shortest list. If your lists might differ in length, use itertools.zip_longest() with a fill value.


7. The Walrus Operator := Assigns and Checks in One Line

Introduced in Python 3.8, this one divides opinion but solves a real problem — avoiding redundant function calls.

import re

data = "Order ID: 4829"

if match := re.search(r"\d+", data):
    print(f"Found number: {match.group()}")  # Found number: 4829

Without the walrus operator, you would call re.search() once to check and again to use. Here you do both in a single expression. Clean, efficient, and underused.


8. *args and **kwargs Are Not Magic — They Are Just Unpacking

A lot of beginners treat these as advanced concepts and avoid them. They are not advanced. They are just flexible argument passing.

def summarize(*args, **kwargs):
    print("Positional:", args)
    print("Keyword:", kwargs)

summarize(1, 2, 3, name="Python", version=3.12)

The * collects extra positional arguments into a tuple. The ** collects extra keyword arguments into a dictionary. That is the entire secret.


9. Use with Statements Beyond Files

Most beginners learn with open(...) and stop there. But the with statement works with anything that implements a context manager — database connections, locks, timers, network sessions.

import time
from contextlib import contextmanager

@contextmanager
def timer():
    start = time.time()
    yield
    print(f"Elapsed: {time.time() - start:.4f}s")

with timer():
    total = sum(range(10_000_000))

Writing your own context managers is a professional habit that makes your code safer and more readable at the same time.


10. List Comprehensions Have a Filter Built In

You do not need to filter a list first and then transform it. The comprehension handles both.

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
even_squares = [n**2 for n in numbers if n % 2 == 0]
print(even_squares)  # [4, 16, 36, 64, 100]

The if at the end is not an afterthought — it is part of the syntax. Use it.


11. any() and all() Replace Verbose Boolean Loops

Checking whether any item in a list meets a condition, or whether all of them do, has a one-liner form that most people never learn.

scores = [78, 85, 92, 60, 88]

print(any(s > 90 for s in scores))   # True
print(all(s >= 60 for s in scores))  # True

These accept any iterable, including generator expressions, which means they are also memory-efficient for large datasets.


12. f-strings Support Expressions, Not Just Variables

Most people use f-strings as slightly nicer string concatenation. But they support full Python expressions inline.

price = 49.99
quantity = 3

print(f"Total: ${price * quantity:.2f}")  # Total: $149.97
print(f"Is bulk order: {quantity > 2}")   # Is bulk order: True

The :2f inside the braces is a format spec. You can apply it to any numeric expression, not just a pre-assigned variable.


13. Automate Repetitive File Tasks With pathlib

The old os.path approach works, but pathlib is how Python wants you to handle files in the modern era.

from pathlib import Path

folder = Path("reports")
folder.mkdir(exist_ok=True)

for file in folder.glob("*.txt"):
    print(file.name, file.stat().st_size)

pathlib treats paths as objects rather than strings. You can chain operations, check existence, read content, and rename files — all without importing five different modules.


14. Dataclasses Cut Boilerplate in Half

Writing a class just to hold some structured data — with __init__, __repr__, and maybe __eq__ — is tedious. Dataclasses generate all of that automatically.

from dataclasses import dataclass

@dataclass
class Article:
    title: str
    author: str
    word_count: int = 0

post = Article("Python Tricks", "My Code Diary", 1200)
print(post)  # Article(title='Python Tricks', author='My Code Diary', word_count=1200)

Use dataclasses whenever you are tempted to write a class that is mostly just storing data. You will write a fraction of the code and get the same result.


15. Generator Functions Scale Where Lists Cannot

Here is the one that genuinely changes how you think about data. When you are processing millions of records, loading everything into a list at once will eventually break your RAM. Generators process one item at a time without storing the rest.

def read_large_file(filepath):
    with open(filepath, "r") as f:
        for line in f:
            yield line.strip()

for line in read_large_file("huge_log.txt"):
    if "ERROR" in line:
        print(line)

The yield keyword is what turns a function into a generator. Each call to next() (which a for loop handles automatically) runs the function until the next yield. The rest of the file sits untouched on disk until you actually need it.

This is how you write Python that scales — not by renting a bigger server, but by being smarter about what you load into memory.


The Honest Truth About Learning Python

None of these tricks are hidden behind paywalls or buried in obscure documentation. They are all in the official Python docs. The reason most beginners do not know them is not a lack of access — it is a lack of exposure at the right moment.

The best way to internalize any of these is to pick one, apply it to a problem you are already working on, and feel the difference. Then move to the next.

The goal is never to write clever code. The goal is to write code that a tired version of yourself can read at midnight and immediately understand. These tricks move you in that direction.

Start with trick five. Build something. Then come back for the rest.


My Code Diary is where I document what four years of Python actually taught me — not what the tutorials promised it would.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top