Python
Asterisk
Programming
Python Syntax
Code Explanation

What does asterisk mean in Python?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

The asterisk (*) in Python serves seven different purposes depending on context: multiplication, exponentiation (**), unpacking iterables in function calls, collecting arguments in function definitions (*args, **kwargs), unpacking in assignments, merging collections, and forcing keyword-only arguments. Knowing which meaning applies comes down to recognizing where the * appears — in an expression, a function signature, or a data structure literal.

1. Multiplication and Exponentiation

python
1# Multiplication
2result = 5 * 3      # 15
3text = "ha" * 3     # "hahaha"
4zeros = [0] * 5     # [0, 0, 0, 0, 0]
5
6# Exponentiation
7result = 2 ** 10    # 1024
8result = 9 ** 0.5   # 3.0 (square root)

2. Unpacking Arguments in Function Calls

* unpacks an iterable into positional arguments. ** unpacks a dict into keyword arguments:

python
1def greet(first, last, greeting):
2    print(f"{greeting}, {first} {last}!")
3
4args = ["Alice", "Smith", "Hello"]
5greet(*args)  # Hello, Alice Smith!
6
7kwargs = {"first": "Bob", "last": "Jones", "greeting": "Hi"}
8greet(**kwargs)  # Hi, Bob Jones!
9
10# Combine both
11positional = ["Alice"]
12keyword = {"last": "Smith", "greeting": "Hey"}
13greet(*positional, **keyword)  # Hey, Alice Smith!

3. Collecting Arguments in Function Definitions

*args collects extra positional arguments into a tuple. **kwargs collects extra keyword arguments into a dict:

python
1def log(message, *args, **kwargs):
2    print(f"Message: {message}")
3    print(f"Extra args: {args}")        # tuple
4    print(f"Extra kwargs: {kwargs}")    # dict
5
6log("hello", 1, 2, 3, level="INFO", timestamp="now")
7# Message: hello
8# Extra args: (1, 2, 3)
9# Extra kwargs: {'level': 'INFO', 'timestamp': 'now'}

This is how functions like print() accept any number of arguments:

python
print("a", "b", "c", sep=", ")  # a, b, c
# print signature: print(*objects, sep=' ', end='\n', ...)

4. Keyword-Only Arguments

A bare * in a function signature forces all following parameters to be keyword-only:

python
1def connect(host, port, *, timeout=30, retries=3):
2    print(f"Connecting to {host}:{port}, timeout={timeout}")
3
4connect("localhost", 8080, timeout=60)     # OK
5connect("localhost", 8080, 60)             # TypeError: takes 2 positional arguments

Everything after * must be passed by name. This prevents ambiguous calls where argument order could be confused.

5. Unpacking in Assignments

python
1# Extended unpacking (Python 3)
2first, *rest = [1, 2, 3, 4, 5]
3print(first)  # 1
4print(rest)   # [2, 3, 4, 5]
5
6head, *middle, tail = [1, 2, 3, 4, 5]
7print(head)    # 1
8print(middle)  # [2, 3, 4]
9print(tail)    # 5
10
11*init, last = [1, 2, 3]
12print(init)  # [1, 2]
13print(last)  # 3

The *variable collects all remaining elements into a list.

6. Merging Collections

python
1# Merge lists (Python 3.5+)
2a = [1, 2, 3]
3b = [4, 5, 6]
4merged = [*a, *b]           # [1, 2, 3, 4, 5, 6]
5merged = [*a, 0, *b]        # [1, 2, 3, 0, 4, 5, 6]
6
7# Merge sets
8s1 = {1, 2}
9s2 = {3, 4}
10merged = {*s1, *s2}         # {1, 2, 3, 4}
11
12# Merge dicts (Python 3.5+)
13d1 = {"a": 1, "b": 2}
14d2 = {"b": 3, "c": 4}
15merged = {**d1, **d2}       # {"a": 1, "b": 3, "c": 4}
16# Later values overwrite earlier for duplicate keys
17
18# Dict merge operator (Python 3.9+)
19merged = d1 | d2            # {"a": 1, "b": 3, "c": 4}

7. In Type Hints

python
1from typing import Unpack, TypedDict
2
3# Variable positional args
4def process(*args: int) -> int:
5    return sum(args)
6
7# Variable keyword args (Python 3.12+)
8class Config(TypedDict):
9    timeout: int
10    retries: int
11
12def setup(**kwargs: Unpack[Config]) -> None:
13    pass

8. Positional-Only Parameters (Python 3.8+)

While / (not *) marks positional-only, they work together:

python
1def func(pos_only, /, normal, *, kw_only):
2    pass
3
4func(1, 2, kw_only=3)       # OK
5func(1, normal=2, kw_only=3) # OK
6func(pos_only=1, normal=2, kw_only=3)  # TypeError

Summary Table

ContextSyntaxMeaning
Expressiona * bMultiplication
Expressiona ** bExponentiation
Function callf(*list)Unpack iterable into positional args
Function callf(**dict)Unpack dict into keyword args
Function defdef f(*args)Collect extra positional args as tuple
Function defdef f(**kwargs)Collect extra keyword args as dict
Function defdef f(*, key)Force keyword-only arguments
Assignmenta, *b = [1,2,3]Extended unpacking into list
Literal[*a, *b]Merge iterables
Literal{**a, **b}Merge dicts

Common Pitfalls

  • Mutable default with * repeat: [[]] * 3 creates [[], [], []] where all three lists are the SAME object. [[] for _ in range(3)] creates three independent lists.
  • *args is a tuple, not a list: You cannot use args.append(). Convert with list(args) if you need mutability.
  • **kwargs loses order in Python < 3.7: In Python 3.7+, dicts preserve insertion order. In earlier versions, kwargs order was undefined.
  • Unpacking in assignment requires iterable: a, *b = 5 raises TypeError because 5 is not iterable. The right side must be a sequence.
  • Double unpacking in function call: f(**d1, **d2) raises TypeError if d1 and d2 share keys (in Python < 3.9). Use f(**{**d1, **d2}) to merge first.

Summary

  • * has seven different meanings in Python depending on context
  • In expressions: multiplication (*) and power (**)
  • In function calls: unpack iterables (*list) and dicts (**dict) into arguments
  • In function definitions: collect extra args (*args) and kwargs (**kwargs)
  • Bare * in function signature forces keyword-only parameters
  • In assignments: extended unpacking (first, *rest = iterable)
  • In literals: merge collections ([*a, *b], {**d1, **d2})

Course illustration
Course illustration

All Rights Reserved.