Here are some practical Python tips and tricks that can make your code more efficient and elegant:
String and Text Manipulation
F-strings for formatting - Use f-strings instead of .format()
or %
formatting:
name, age = "Alice", 30
print(f"{name} is {age} years old") # Clean and readable
Multiline strings with triple quotes - Great for SQL queries or documentation:
query = """
SELECT name, email
FROM users
WHERE active = 1
"""
List and Dictionary Operations
List comprehensions - More concise than traditional loops:
squares = [x**2 for x in range(10) if x % 2 == 0] # Even squares only
Dictionary comprehensions:
word_lengths = {word: len(word) for word in ["python", "java", "go"]}
Use get()
for safe dictionary access:
user_age = user_data.get("age", 0) # Returns 0 if "age" key doesn't exist
Control Flow and Logic
Chained comparisons:
if 18 <= age <= 65: # Much cleaner than age >= 18 and age <= 65
print("Working age")
Use any()
and all()
for boolean operations:
if any(x > 10 for x in numbers): # True if any number > 10
if all(score >= 60 for score in scores): # True if all scores >= 60
Function and Class Tricks
Default mutable arguments - Avoid the common pitfall:
# Wrong way
def add_item(item, target_list=[]): # Dangerous!
# Right way
def add_item(item, target_list=None):
if target_list is None:
target_list = []
Use *args
and `kwargs` for flexible functions**:
def flexible_func(*args, **kwargs):
print(f"Args: {args}, Kwargs: {kwargs}")
Built-in Functions and Modules
enumerate()
instead of manual counting:
for i, item in enumerate(items):
print(f"{i}: {item}")
zip()
for parallel iteration:
names = ["Alice", "Bob", "Charlie"]
ages = [25, 30, 35]
for name, age in zip(names, ages):
print(f"{name}: {age}")
collections.Counter
for counting:
from collections import Counter
letter_counts = Counter("hello world")
pathlib
for file operations:
from pathlib import Path
file_path = Path("data") / "file.txt" # Cross-platform path handling
Performance and Memory
Use generators for large datasets:
def fibonacci():
a, b = 0, 1
while True:
yield a
a, b = b, a + b
List slicing tricks:
# Reverse a list
reversed_list = original_list[::-1]
# Get every nth element
every_third = my_list[::3]
Error Handling
EAFP (Easier to Ask for Forgiveness than Permission):
# Pythonic way
try:
value = my_dict["key"]
except KeyError:
value = "default"
# Instead of
if "key" in my_dict:
value = my_dict["key"]
else:
value = "default"
Context Managers
Always use context managers for file operations:
with open("file.txt") as f:
content = f.read()
# File automatically closed, even if exception occurs
Debugging and Development
Use pprint
for complex data structures:
from pprint import pprint
pprint(complex_nested_dict) # Much more readable output
breakpoint()
for debugging (Python 3.7+):
# Instead of import pdb; pdb.set_trace()
breakpoint() # Drops into debugger
These techniques can significantly improve your Python code's readability, performance, and maintainability. The key is knowing when to apply each one based on your specific use case.
Top comments (1)
Great collection of Python tips! These cover readability, efficiency, and maintainability very well. I especially like how you highlighted pitfalls like mutable default arguments and solutions like context managers. Using built-ins like enumerate, zip, and Counter really simplifies code. A handy reference for writing cleaner, more Pythonic programs.