Defining Functions in Python

Data Science Tool Box Mar 18, 2026

Defining Functions in Python

Well-written functions are the backbone of clean, reusable, and maintainable data science code. In 2026, following modern Python standards for function definition helps you create modular, testable, and professional-grade data pipelines.

TL;DR — Modern Function Definition Best Practices

  • Use type hints for parameters and return values
  • Always include a clear docstring
  • Keep functions small and focused (single responsibility)
  • Use default arguments wisely

1. Modern Function Definition with Type Hints

from typing import List, Optional

import pandas as pd
from datetime import datetime

def calculate_monthly_revenue(
    transactions: List[dict],
    month: int,
    year: int = 2026
) -> float:
    """
    Calculate total revenue for a given month and year.
    
    Args:
        transactions: List of transaction dictionaries
        month: Month number (1-12)
        year: Year (default: current year)
    
    Returns:
        Total revenue as float
    """
    total = 0.0
    for tx in transactions:
        tx_date = datetime.fromisoformat(tx["date"])
        if tx_date.month == month and tx_date.year == year:
            total += tx.get("amount", 0.0)
    return round(total, 2)

2. Real-World Data Science Function Example

def clean_and_summarize_sales(
    df,
    min_amount: float = 0.0,
    region: Optional[str] = None
) -> pd.DataFrame:
    """
    Clean sales data and return summary statistics.
    """
    # Filter and clean
    cleaned = df[df["amount"] >= min_amount].copy()
    
    if region:
        cleaned = cleaned[cleaned["region"] == region]
    
    # Add useful columns
    cleaned = cleaned.assign(
        year=cleaned["order_date"].dt.year,
        month_name=cleaned["order_date"].dt.month_name()
    )
    
    # Return summary
    summary = cleaned.groupby("region").agg({
        "amount": ["sum", "mean", "count"],
        "customer_id": "nunique"
    }).round(2)
    
    return summary

3. Best Practices for Data Science Functions in 2026

  • Always add clear, informative docstrings (Google or NumPy style)
  • Use type hints for all parameters and return values
  • Keep functions focused on doing one thing well
  • Use descriptive parameter and function names
  • Provide sensible default values where appropriate
  • Return clean, consistent data types

Anatomy of a Good Function

A function bundles a task under a name: def, a name, parameters, a body and a return value. Good data functions do one job, take inputs as parameters rather than reading globals, and return results instead of printing them.

Type hints and a short docstring document what goes in and what comes out. Small pure functions like these are easy to test and easy to reuse across notebooks.

Worked Example: A Reusable Cleaning Function

A function cleans a price column and is tested with a quick assertion.

import pandas as pd

def clean_prices(df: pd.DataFrame, column: str = "price") -> pd.DataFrame:
    """Return a copy with the price column as float and negatives removed."""
    out = df.copy()
    out[column] = pd.to_numeric(out[column], errors="coerce")
    return out[out[column] >= 0]

raw = pd.DataFrame({"price": ["10.5", "-3", "abc", "7"]})
result = clean_prices(raw)
print(result)
assert result["price"].tolist() == [10.5, 7.0]
print("test passed")

The function never changes the input, because it works on a copy. Invalid text becomes NaN and is filtered out along with the negative value, and the assertion acts as a tiny test.

Practical Tips

Keep functions short enough to read on one screen. If a function needs comments to separate its stages, those stages are often better as separate functions with clear names. In notebooks, move stable functions into a .py module and import them, so the same logic is shared across analyses instead of being copied between cells and drifting apart over time.

Finally, give functions verb-based names such as clean_prices or load_orders, so the call site reads like a description of the work being done.

Before writing a function, try writing the call you want to make. If the call reads clearly, the signature is probably right; if it needs many arguments, the function may be doing too much.

Common Mistakes

  • Printing results instead of returning them.
  • Changing the input DataFrame in place unexpectedly.
  • Relying on global variables inside the function.
  • Writing one function that does many unrelated jobs.

Quick Summary

  • Use def, clear parameters and a return value.
  • Keep each function focused on one task.
  • Add type hints and a docstring.
  • Test small functions with assertions.

Conclusion

Writing good functions is one of the most important skills in data science. In 2026, the standard is to define functions with type hints, comprehensive docstrings, and clear single responsibility. Well-designed functions make your data science code reusable, testable, and much easier to maintain as projects grow.

Next steps:

  • Review your current data science scripts and refactor repeated logic into well-documented, typed functions

Related Tutorials

Share:
Last updated: March 2026
Built-in Functions in Python 2026 str() in Python 2026: String Conversion + Modern Formatting & Best Practices memoryview with JAX in Python 2026: Zero-Copy NumPy → JAX Array Interop + Efficient ML Examples memoryview with TensorFlow in Python 2026: Zero-Copy NumPy → Tensor Interop + GPU Pinning & ML Examples memoryview with TensorFlow in Python 2026: Zero-Copy NumPy → Tensor Interop + ML Examples memoryview with NumPy & PyTorch in Python 2026: Zero-Copy Views, Efficient Slicing & ML Interop Examples memoryview with NumPy in Python 2026: Zero-Copy Views, Efficient Slicing & Real ML Examples memoryview() in Python 2026: Zero-Copy Magic for Large Binary Data + Real Examples import() in Python 2026: How It Works, Security Risks & Modern Alternatives (importlib) zip() in Python 2026: How to Use It, strict=True Behavior & Real-World Examples vars() in Python 2026: Accessing Object Namespace + Modern Introspection Patterns type() in Python 2026: Dynamic Type Inspection & Object Creation + Modern Patterns tuple() in Python 2026: Immutable Sequences + Modern Patterns & Best Practices super() in Python 2026: Method Resolution & Modern Inheritance Patterns sum() in Python 2026: Summing Iterables + Modern Numeric Patterns & Best Practices staticmethod() in Python 2026: Static Methods, Utility Functions & Modern Best Practices sorted() in Python 2026: Sorting Iterables + Modern Patterns & Best Practices slice() in Python 2026: Creating Slice Objects + Modern Patterns & Best Practices setattr() in Python 2026: Dynamic Attribute Setting + Modern Patterns & Safety set() in Python 2026: Mutable Sets Creation + Modern Patterns & Best Practices