Learn Python from scratch. Hands-on lessons, projects, and a community to help you go from zero to confident coder.
Location hidden
Created byProfile pictureRaphael Moses
11 joined
Profile picture
Raphael MosesProfile picture@delight010·Mar 25

🔥 Python Tip: itertools — Powerful Iteration Tools

The itertools module gives you super-powered loops without writing complex code.


Chain — Combine Iterables

from itertools import chain

list1 = [1, 2, 3]
list2 = [4, 5, 6]
list3 = [7, 8, 9]

for num in chain(list1, list2, list3):
    print(num, end=' ')  # 1 2 3 4 5 6 7 8 9


Product — All Combinations

from itertools import product

colors = ['red', 'blue']
sizes = ['S', 'M', 'L']

for color, size in product(colors, sizes):
    print(f"{color}-{size}", end=' ')
# red-S red-M red-L blue-S blue-M blue-L


Groupby — Group Consecutive Items

from itertools import groupby

data = sorted([
    ('A', 1), ('B', 2), ('A', 3), ('B', 4)
])

for key, group in groupby(data, key=lambda x: x[0]):
    print(f"{key}: {list(group)}")
# A: [('A', 1), ('A', 3)]
# B: [('B', 2), ('B', 4)]


Islice — Slice Any Iterable

from itertools import islice

def fibonacci():
    a, b = 0, 1
    while True:
        yield a
        a, b = b, a + b

# Get first 10 Fibonacci numbers
first_10 = list(islice(fibonacci(), 10))
print(first_10)  # [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]


💡 itertools is memory-efficient because it works with generators — perfect for processing large datasets!

Profile picture
Raphael MosesProfile picture@delight010·Mar 25

🔥 Python Tip: collections Module — defaultdict, Counter, namedtuple

The collections module has powerful data structures that solve common problems elegantly.


Counter — Count Anything

from collections import Counter

words = "the cat sat on the mat the cat".split()
count = Counter(words)
print(count.most_common(3))
# [('the', 3), ('cat', 2), ('sat', 1)]


defaultdict — No More KeyError

from collections import defaultdict

# Group items by category
items = [("fruit", "apple"), ("veg", "carrot"), ("fruit", "banana")]

grouped = defaultdict(list)
for category, item in items:
    grouped[category].append(item)

print(dict(grouped))
# {'fruit': ['apple', 'banana'], 'veg': ['carrot']}


namedtuple — Lightweight Classes

from collections import namedtuple

Point = namedtuple('Point', ['x', 'y'])
p = Point(3, 4)
print(p.x, p.y)  # 3 4
print(p)          # Point(x=3, y=4)


💡 Before writing a custom class, check if collections already has what you need!

Profile picture
Raphael MosesProfile picture@delight010·Mar 25

🔥 Python Tip: @property — Getter/Setter the Pythonic Way

Want controlled access to your class attributes? Use @property instead of Java-style getters and setters!


class Temperature:
    def __init__(self, celsius):
        self._celsius = celsius
    
    @property
    def celsius(self):
        return self._celsius
    
    @celsius.setter
    def celsius(self, value):
        if value < -273.15:
            raise ValueError("Below absolute zero!")
        self._celsius = value
    
    @property
    def fahrenheit(self):
        return self._celsius * 9/5 + 32

temp = Temperature(25)
print(temp.celsius)     # 25
print(temp.fahrenheit)  # 77.0

temp.celsius = 100      # Uses the setter
print(temp.fahrenheit)  # 212.0

# temp.celsius = -300  # Raises ValueError!


💡 Properties let you start with simple attributes and add validation later — without changing the interface. That's clean Python!

Profile picture
Raphael MosesProfile picture@delight010·Mar 25

🔥 Python Tip: The `with` Statement — Context Managers Simplified

Stop manually closing files and connections. The with statement handles cleanup automatically!


File Handling

# ❌ Old way — might not close if error occurs
f = open('file.txt', 'r')
data = f.read()
f.close()

# ✅ with statement — always closes!
with open('file.txt', 'r') as f:
    data = f.read()
# File is closed here automatically


Multiple Context Managers

with open('input.txt') as src, open('output.txt', 'w') as dst:
    dst.write(src.read().upper())


Make Your Own

from contextlib import contextmanager

@contextmanager
def timer():
    import time
    start = time.time()
    yield
    print(f"Took {time.time() - start:.2f}s")

with timer():
    sum(range(10_000_000))
# Output: Took 0.32s


💡 Any time you have setup + cleanup logic, a context manager is your best friend!

Profile picture
Raphael MosesProfile picture@delight010·Mar 25

🔥 Python Tip: Try/Except — Handle Errors Like a Pro

Errors will happen. The difference between a beginner and a pro is how you handle them.


Basic Error Handling

try:
    result = 10 / 0
except ZeroDivisionError:
    print("Can't divide by zero!")


Catch Multiple Exceptions

try:
    value = int(input("Enter a number: "))
    result = 100 / value
except ValueError:
    print("That's not a valid number!")
except ZeroDivisionError:
    print("Can't divide by zero!")
except Exception as e:
    print(f"Unexpected error: {e}")
finally:
    print("This always runs!")


Pro Pattern: EAFP

Python follows EAFP — Easier to Ask Forgiveness than Permission:

# ❌ Look Before You Leap (LBYL)
if key in my_dict:
    value = my_dict[key]

# ✅ EAFP — more Pythonic!
try:
    value = my_dict[key]
except KeyError:
    value = default_value


💡 Pro tip: Never use a bare except: — always catch specific exceptions!

Profile picture
@lde41Profile pictureMar 1

🔥 Python Tip: map() and filter() Made Simple

Two built-in functions that make data transformation a breeze.


map() — apply a function to every item:

nums = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x**2, nums))
# [1, 4, 9, 16, 25]

# With a named function
def celsius_to_fahrenheit(c):
    return (c * 9/5) + 32

temps_c = [0, 20, 37, 100]
temps_f = list(map(celsius_to_fahrenheit, temps_c))
# [32.0, 68.0, 98.6, 212.0]


filter() — keep items that pass a test:

nums = range(1, 21)
evens = list(filter(lambda x: x % 2 == 0, nums))
# [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]

words = ["hello", "", "world", "", "python"]
non_empty = list(filter(None, words))
# ["hello", "world", "python"]


Chaining them together:

# Get squares of even numbers only
nums = range(1, 11)
result = list(map(lambda x: x**2, filter(lambda x: x % 2 == 0, nums)))
# [4, 16, 36, 64, 100]


💡 Tip: List comprehensions can often replace map/filter and are more Pythonic:

[x**2 for x in range(1, 11) if x % 2 == 0]


Know both — use whichever reads better for your use case! ✨

Profile picture
@lde41Profile pictureMar 1

🔥 Python Tip: Lambda Functions in One Line

Lambda functions are small anonymous functions you can define in a single line.


Syntax:

lambda arguments: expression


Examples:

# Simple lambda
double = lambda x: x * 2
double(5)  # 10

# Multiple arguments
add = lambda x, y: x + y
add(3, 4)  # 7


Where lambdas really shine — sorting:

students = [
    {"name": "Alice", "gpa": 3.8},
    {"name": "Bob", "gpa": 3.5},
    {"name": "Charlie", "gpa": 3.9}
]

# Sort by GPA descending
students.sort(key=lambda s: s["gpa"], reverse=True)
# Charlie (3.9), Alice (3.8), Bob (3.5)


With map() and filter():

nums = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x**2, nums))
# [1, 4, 9, 16, 25]

evens = list(filter(lambda x: x % 2 == 0, nums))
# [2, 4]


⚠️ Rule of thumb: If your lambda is complex, use a regular function instead. Readability counts! 🐍

Profile picture
@lde41Profile pictureMar 1

🔥 Python Tip: *args and **kwargs Explained

Ever seen args and *kwargs in Python functions and wondered what they do? Let's break it down.


*args — captures extra positional arguments as a tuple:

def add(*args):
    return sum(args)

add(1, 2, 3)      # 6
add(10, 20)        # 30
add(1, 2, 3, 4, 5) # 15


**kwargs — captures extra keyword arguments as a dictionary:

def greet(**kwargs):
    for key, value in kwargs.items():
        print(f"{key}: {value}")

greet(name="Alice", age=30, city="NYC")
# name: Alice
# age: 30
# city: NYC


Combine them all:

def super_func(required, *args, **kwargs):
    print(f"Required: {required}")
    print(f"Args: {args}")
    print(f"Kwargs: {kwargs}")

super_func("hello", 1, 2, 3, color="red")
# Required: hello
# Args: (1, 2, 3)
# Kwargs: {"color": "red"}


The order matters: regular → args → *kwargs


This is how libraries like Flask and Django build flexible APIs! 🔧

Profile picture
@lde41Profile pictureMar 1

🔥 Python Tip: Dictionary Comprehensions

Just like list comprehensions, Python has dictionary comprehensions — and they're incredibly useful.


Basic syntax:

{key: value for item in iterable}


Examples:

# Square mapping
squares = {x: x**2 for x in range(6)}
# {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25}

# Invert a dictionary
original = {"a": 1, "b": 2, "c": 3}
inverted = {v: k for k, v in original.items()}
# {1: "a", 2: "b", 3: "c"}

# Filter a dictionary
scores = {"Alice": 95, "Bob": 67, "Charlie": 82}
high_scorers = {k: v for k, v in scores.items() if v >= 80}
# {"Alice": 95, "Charlie": 82}


Real-world use case:

# Count word frequency
words = ["apple", "banana", "apple", "cherry", "banana", "apple"]
freq = {w: words.count(w) for w in set(words)}
# {"apple": 3, "banana": 2, "cherry": 1}


Clean, readable, and fast. Try converting one of your for loops today! 🎯

Profile picture
@lde41Profile pictureMar 1

🔥 Python Tip: zip() — Loop Through Multiple Lists at Once

Need to iterate over two (or more) lists at the same time? Use zip()!


❌ The clunky way:

names = ["Alice", "Bob", "Charlie"]
scores = [95, 87, 92]

for i in range(len(names)):
    print(f"{names[i]}: {scores[i]}")


✅ The Pythonic way:

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


Bonus tricks:

# Unzip with zip(*)
pairs = [("a", 1), ("b", 2), ("c", 3)]
letters, numbers = zip(*pairs)
# letters = ("a", "b", "c")
# numbers = (1, 2, 3)

# Create a dict from two lists
names = ["Alice", "Bob"]
scores = [95, 87]
result = dict(zip(names, scores))
# {"Alice": 95, "Bob": 87}


zip() stops at the shortest list. Use itertools.zip_longest() if you need all elements! 💡