mailwal

Python From Scratch #35 - *args in Python

Shefali Jangid

Python From Scratch #35 - *args in Python

Learn how to use *args to accept any number of positional arguments in Python.

Hey 👋

So far, we’ve learned how to pass arguments to functions:

def greet(name):
    print("Hello", name)

greet("Shefali")

But what if you don’t know how many arguments you’ll need?

For example, what if you want a function that can accept any number of values?

That’s where *args comes in.

What is *args?

*args allows a function to accept any number of positional arguments.

For example:

def add_numbers(*args):
    print(args)

add_numbers(10, 20, 30)

# Output:

# (10, 20, 30)

Notice that the values are displayed inside parentheses.

Python collects all the positional arguments into a tuple.

We’ll learn more about tuples later. For now, just remember: *args collects multiple positional arguments into one variable.

*args Is a Tuple

As we just saw, *args collects the arguments into a tuple.

Remember from lesson #9 that tuples are immutable. That means you can read their values, but you can’t change them.

For example:

def change(*args):
    args[0] = 99

change(1, 2, 3)

This raises: TypeError: 'tuple' object does not support item assignment

Since *args is a tuple, you can read its values but not change them.

Why Do We Need *args?

Normally, you need to define how many parameters a function accepts:

def add_numbers(a, b):
    print(a + b)

add_numbers(10, 20)

This function expects exactly two arguments.

If you try add_numbers(10, 20, 30), Python raises an error because the function only has two parameters.

With *args, you can accept as many positional arguments as you need:

def add_numbers(*args):
    print(args)

add_numbers(10, 20, 30, 40, 50)

# Output:

# (10, 20, 30, 40, 50)

args Is Just a Name

The name args is not special.

The * is what matters.

For example:

def add_numbers(*numbers):
    print(numbers)

add_numbers(10, 20, 30)

# Output:

# (10, 20, 30)

You could technically call it anything:

def add_numbers(*values):
    print(values)

But *args is the common convention, so you’ll see it often in Python code.

Looping Through *args

Since the collected values can be worked with one by one, you can loop through them:

def show_numbers(*args):
    for number in args:
        print(number)

show_numbers(10, 20, 30)

# Output:

# 10
# 20
# 30

You can also use len():

def count_numbers(*args):
    print("You provided", len(args), "numbers.")

count_numbers(10, 20, 30, 40)

# Output:

# You provided 4 numbers.

This uses things you’ve already learned:

  • functions

  • arguments

  • for loops

  • len()

Using *args to Add Numbers

Now let’s make our earlier example more useful:

def add_numbers(*args):
    total = 0

    for number in args:
        total = total + number

    return total

result = add_numbers(10, 20, 30)

print(result)

# Output:

# 60

The function can now accept any number of numbers:

print(add_numbers(5, 10))
print(add_numbers(5, 10, 15))
print(add_numbers(5, 10, 15, 20, 25))

# Output:

# 15
# 30
# 75

That’s the main benefit of *args.

You don’t have to decide in advance how many positional arguments the function should accept.

A Quick Note About sum()

Python already has a built-in sum() function that adds a collection of numbers.

For example:

numbers = (10, 20, 30)
print(sum(numbers))

# Output:

# 60

We wrote our own add_numbers() function above to understand how *args works.

In real code, if you simply need to add a collection of numbers, Python’s built-in sum() is usually the simpler choice.

*args With Regular Parameters

You can also use regular parameters together with *args.

For example:

def greet(greeting, *names):
    for name in names:
        print(greeting, name)

greet("Hello", "Shefali", "John", "Mark")

# Output:

# Hello Shefali
# Hello John
# Hello Mark

Here:

  • greeting receives "Hello"

  • *names collects the remaining positional arguments

So names contains: ("Shefali", "John", "Mark")

One Important Rule

When you use a regular parameter before *args, the regular parameter gets its value first.

For example:

def show(first, *others):
    print("First:", first)
    print("Others:", others)

show(10, 20, 30, 40)

# Output:

# First: 10
# Others: (20, 30, 40)

The first argument goes to first and the remaining positional arguments are collected by *others.

*args Doesn’t Mean “Any Type”

*args controls how many positional arguments a function accepts.

It doesn’t mean all the arguments have to be the same type.

For example:

def show_values(*args):
    print(args)

show_values(10, "Hello", 3.14)

# Output:

# (10, 'Hello', 3.14)

You can pass different types of values.

*args vs Normal Parameters

Here’s the difference:

Normal parameters

def add(a, b):
    return a + b

The function expects two arguments.

With *args

def add(*args):
    total = 0

    for number in args:
        total = total + number

    return total

The function can accept any number of positional arguments.

add(1, 2)
add(1, 2, 3)
add(1, 2, 3, 4, 5)

What Happens If You Don’t Pass Anything?

You can call a *args function without providing any arguments:

def show_values(*args):
    print(args)

show_values()

# Output:

# ()

The function receives an empty tuple.

This can be useful when you want a function to accept zero or more values.

A Common Mistake

Don’t forget the *.

This:

def show_values(args):
    print(args)

is a normal parameter.

It expects one argument: show_values(10)

But this:

def show_values(*args):
    print(args)

can accept multiple positional arguments: show_values(10, 20, 30)

So the * changes how Python collects the arguments.

Try It Yourself

Now, a small exercise for you. Try these:

  • Create a function called show_items() that accepts any number of items and prints each item on a new line.

  • Create a function called count_items() that accepts any number of arguments and prints how many items were provided.

That’s all for today!

Tomorrow, we’ll look at **kwargs and learn how functions can accept any number of keyword arguments.


If you enjoyed this newsletter, consider sharing it with another developer. And if you have any feedback, I’d love to hear it. It would genuinely mean a lot to me. ❤️


Want to sponsor my work? Let’s talk!

See you tomorrow ✨

- Shefali

Thanks for reading DevBits by Shefali! Subscribe for free to receive new posts and support my work.

If you enjoyed this edition of DevBits, you can support my work here ☕

Buy Me a Coffee

Your support helps me keep creating more developer tips, UI snippets, and helpful content for the community.

© 2026 Shefali Jangid
548 Market Street PMB 72296, San Francisco, CA 94104