Multiple Parameters and Return Values in Python Functions

Data Science Tool Box Mar 18, 2026

Multiple Parameters and Return Values in Python Functions

Handling multiple parameters and returning multiple values is very common in data science workflows. In 2026, following modern Python conventions helps you write clean, readable, and maintainable functions for data processing, modeling, and analysis.

TL;DR — Recommended Patterns

  • Use type hints for all parameters and return values
  • Use keyword-only parameters for important options
  • Return multiple values using tuples or dataclasses
  • Prefer structured return types over raw tuples when possible

1. Function with Multiple Parameters

from typing import List, Tuple, Optional
import pandas as pd

def prepare_modeling_data(
    df: pd.DataFrame,
    target_column: str,
    feature_columns: Optional[List[str]] = None,
    *,
    handle_missing: bool = True,
    test_size: float = 0.2,
    random_state: int = 42
) -> Tuple[pd.DataFrame, pd.DataFrame, pd.Series, pd.Series]:
    """
    Prepare data for machine learning modeling.
    
    Args:
        df: Input DataFrame
        target_column: Name of the target variable
        feature_columns: List of feature columns (if None, uses all except target)
        handle_missing: Whether to drop rows with missing values
        test_size: Proportion of data to use for testing
        random_state: Random seed for reproducibility
    
    Returns:
        Tuple containing (X_train, X_test, y_train, y_test)
    """
    if feature_columns is None:
        feature_columns = [col for col in df.columns if col != target_column]
    
    if handle_missing:
        df = df.dropna(subset=feature_columns + [target_column])
    
    X = df[feature_columns]
    y = df[target_column]
    
    from sklearn.model_selection import train_test_split
    X_train, X_test, y_train, y_test = train_test_split(
        X, y, test_size=test_size, random_state=random_state
    )
    
    return X_train, X_test, y_train, y_test

2. Better Approach: Using a Dataclass for Multiple Return Values

from dataclasses import dataclass
from typing import Any

@dataclass
class ModelingResults:
    model: Any
    metrics: dict
    feature_importance: dict
    predictions: pd.Series

def train_classification_model(
    X_train, y_train, X_test, y_test, model_type: str = "random_forest"
) -> ModelingResults:
    """Train a model and return structured results."""
    # Training logic here...
    
    return ModelingResults(
        model=model,
        metrics={"accuracy": 0.89, "f1": 0.87, "auc": 0.92},
        feature_importance=feature_importance,
        predictions=predictions
    )

3. Best Practices in 2026

  • Use type hints for all parameters and return values
  • Use keyword-only parameters (*) for configuration options
  • Return multiple values using a dataclass instead of a plain tuple when the return value is complex
  • Keep the number of parameters reasonable (ideally under 6-7)
  • Provide sensible default values for optional parameters
  • Document complex parameters and return values clearly in the docstring

Several Inputs, Several Outputs

Functions often need several inputs and produce several results. Python handles outputs by returning a tuple, which callers can unpack into separate names in one line.

Once a function returns more than three values, unpacking by position becomes fragile. A dictionary or a dataclass names each result, so adding a new value later does not break existing callers.

Worked Example: Tuple versus Dataclass

A train and test split is returned as a tuple, and a summary is returned as a dataclass.

from dataclasses import dataclass

def split(values, ratio=0.8):
    cut = int(len(values) * ratio)
    return values[:cut], values[cut:]

train, test = split(list(range(10)))
print(train, test)

@dataclass
class Summary:
    total: float
    mean: float
    count: int

def summarize(values):
    return Summary(sum(values), sum(values) / len(values), len(values))

s = summarize([2.0, 4.0, 9.0])
print(s.total, s.mean, s.count)

Unpacking into train and test is clear for two values. The dataclass version names every field, prints readably, and can grow without changing how callers use it.

Practical Tips

When a function takes many inputs, consider grouping related settings into one configuration object or dictionary. Calls stay short, and new settings can be added without changing every call site.

Type hints help here too. Annotating the return as tuple[list, list] or as the dataclass name tells readers and editors exactly what comes back.

Common Mistakes

  • Unpacking into the wrong number of names.
  • Returning many unnamed values.
  • Swapping the order of two similar outputs.
  • Passing many positional inputs without keywords.

Quick Summary

  • Return tuples for two or three values.
  • Unpack them on assignment.
  • Use dataclasses or dicts for more values.
  • Prefer keyword arguments for many inputs.

Conclusion

Handling multiple parameters and return values properly is a hallmark of professional data science code. In 2026, the best practice is to use type hints, keyword-only parameters for options, and structured return types (dataclasses) instead of raw tuples. These patterns make your functions more readable, maintainable, and easier for other data scientists to use.

Next steps:

  • Review your current data science functions and improve them by adding type hints and using dataclasses for complex return values

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