1. List Comprehensions: Concise Data Manipulation
List comprehensions offer a compact way to create lists based on existing iterables. They often replace more verbose for loops, improving code readability and performance.
squares = []
for x in range(10):
squares.append(x**2)
print(squares) # Output: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
squares = [x**2 for x in range(10)]
print(squares) # Output: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
#Conditional List Comprehension
even_squares = [x**2 for x in range(10) if x % 2 == 0]
print(even_squares) # Output: [0, 4, 16, 36, 64]2. Generator Expressions: Memory Efficiency
Generator expressions are similar to list comprehensions, but instead of creating an entire list in memory, they generate values on demand. This is especially beneficial when dealing with large datasets.
large_squares = [x**2 for x in range(1000000)]
large_squares_gen = (x**2 for x in range(1000000))
for sq in large_squares_gen:
#Process each square efficiently
pass # replace pass with your processing logic.3. Lambda Functions: Anonymous Functions
Lambda functions are small, anonymous functions defined using the lambda keyword. They’re often used as arguments to higher-order functions like map, filter, and sorted.
def add(x, y):
return x + y
add_lambda = lambda x, y: x + y
print(add(5, 3)) # Output: 8
print(add_lambda(5, 3)) # Output: 8
#Using lambda with map
numbers = [1, 2, 3, 4, 5]
squared_numbers = list(map(lambda x: x**2, numbers))
print(squared_numbers) # Output: [1, 4, 9, 16, 25]4. Decorators: Modifying Function Behavior
Decorators provide a clean way to wrap additional functionality around an existing function without modifying its core logic.
import time
def my_decorator(func):
def wrapper():
start_time = time.time()
func()
end_time = time.time()
print(f"Function execution time: {end_time - start_time:.4f} seconds")
return wrapper
@my_decorator
def say_hello():
print("Hello!")
say_hello() #Output: Hello! and the execution time.5. Context Managers: Resource Management
Context managers (with statement) simplify resource management (e.g., file handling, database connections). They ensure resources are properly acquired and released, even in case of exceptions.
with open("my_file.txt", "w") as f:
f.write("This is some text.")6. *args and **kwargs: Flexible Function Arguments
*args allows a function to accept a variable number of positional arguments, while **kwargs allows a variable number of keyword arguments.
def my_function(*args, **kwargs):
print("Positional arguments:", args)
print("Keyword arguments:", kwargs)
my_function(1, 2, 3, name="Alice", age=30)These advanced techniques empower you to write more Pythonic, efficient, and maintainable code. They are essential tools for any Python programmer aiming to advance their skills.