Blog

How *args and **kwargs Make Your Functions More Flexible

How *args and **kwargs Make Your Functions More Flexible

Ever found yourself writing functions that need to handle different numbers of inputs? Maybe you're analyzing datasets with varying numbers of columns, or building a simulation that sometimes needs 3 parameters, sometimes 10?

If you've been copy-pasting functions or creating multiple versions of the same code, there's a better way. Meet *args and **kwargs—Python's secret weapons for flexible functions.

Don't worry about the weird syntax. By the end of this post, you'll understand exactly what they do and how they can make your research code cleaner and more adaptable.

What Are *args and **kwargs?

Think of them as Python's way of saying "I don't know exactly what you'll pass me, but I'm ready for anything."

*args (arguments) lets your function accept any number of positional arguments.

**kwargs (keyword arguments) lets your function accept any number of named arguments.

Here's the simplest example:

def flexible_function(*args, **kwargs):
    print("Positional arguments:", args)
    print("Keyword arguments:", kwargs)

flexible_function(1, 2, 3, name="Alice", age=30)

The function received 3 numbers and 2 named parameters, and handled them all gracefully.

Real Research Examples

Example 1: Flexible Data Analysis Function

def analyze_conditions(*conditions, method="mean", **analysis_options):
    results = []
    for condition in conditions:
        if method == "mean":
            result = sum(condition) / len(condition)
        elif method == "median":
            result = sorted(condition)[len(condition)//2]
        results.append(result)
    if analysis_options.get("normalize", False):
        max_val = max(results)
        results = [r/max_val for r in results]
    return results

Example 2: Flexible Plotting Function

import matplotlib.pyplot as plt

def plot_multiple_datasets(*datasets, **plot_options):
    fig, ax = plt.subplots()
    for i, dataset in enumerate(datasets):
        ax.plot(dataset, label=f"Dataset {i+1}")
    ax.set_title(plot_options.get("title", "Multiple Datasets"))
    ax.set_xlabel(plot_options.get("xlabel", "X-axis"))
    ax.set_ylabel(plot_options.get("ylabel", "Y-axis"))
    if plot_options.get("show_legend", True):
        ax.legend()
    if plot_options.get("grid", False):
        ax.grid(True)
    return fig

Why This Matters for Your Research

  • Adaptable: One function handles multiple scenarios instead of writing separate functions
  • Reusable: Share your functions with colleagues who might have different data structures
  • Future-proof: Add new options without breaking existing code
  • Clean: No more copy-pasting similar functions

Common Patterns You'll Use

Pattern 1: Optional Parameters

def run_simulation(base_params, **optional_params):
    config = {
        'iterations': 1000,
        'seed': 42,
        'verbose': False
    }
    config.update(optional_params)
    return simulate(base_params, config)

Pattern 2: Passing Arguments Along

def enhanced_analysis(data, *args, **kwargs):
    cleaned_data = preprocess(data)
    return main_analysis(cleaned_data, *args, **kwargs)

TL;DR

  • *args lets functions accept any number of positional arguments
  • **kwargs lets functions accept any number of keyword arguments
  • They make your functions more flexible and reusable
  • Perfect for research code that needs to handle varying inputs

Quick Practice

def calculate_stats(*data_arrays, **options):
    # Your code here
    pass

How would you make it handle different statistical measures based on the options?

Final Thought

*args and **kwargs might look intimidating at first, but they're just Python's way of making your functions more accommodating. Think of them as the "one size fits all" solution for function parameters.

Once you start using them, you'll wonder how you ever lived without them! 🎯

Dr Victor Gambarini

Dr Victor Gambarini

Dr Victor Gambarini is a bioinformatician and systems engineer with a PhD from the University of Auckland, specializing in microbiome research and environmental genomics. His work has contributed to many peer-reviewed publications, including studies on plastic biodegradation, sugarcane rhizosphere microbiota, and iNKT cell function in metabolic disease. Victor’s core expertise lies in the analysis of next-generation sequencing data, multi-omics integration, and co-expression network analysis. He combines advanced programming skills in Python and R with experience in high-performance computing and cloud infrastructure, making him uniquely positioned to bridge research and computational scalability. Fluent in both English and Portuguese, Victor has international experience across Brazil, the U.S., and New Zealand.