Language
日本語
English

Caution

JavaScript is disabled in your browser.
This site uses JavaScript for features such as search.
For the best experience, please enable JavaScript before browsing this site.

Python Dictionary

  1. Home
  2. Python Dictionary
  3. *args / **kwargs

*args / **kwargs

In Python, *args accepts any number of positional arguments as a tuple, and **kwargs accepts any number of keyword arguments as a dictionary. When combining both, the argument order (regular args → *args → keyword-only args → **kwargs) must be followed. On the caller side, lists and dictionaries can be unpacked with *list and **dict.

Syntax

# *args: accepts any number of positional arguments as a tuple
def func_name(*args):
    for item in args:
        print(item)

# **kwargs: accepts any number of keyword arguments as a dictionary
def func_name(**kwargs):
    for key, value in kwargs.items():
        print(key, value)

# Combined (order matters)
def func_name(regular_arg, *args, keyword_only_arg, **kwargs):
    pass

# Unpacking on the caller side
func_name(*my_list)   # expands a list as positional arguments
func_name(**my_dict)  # expands a dict as keyword arguments

Argument Order Rules

OrderTypeExampleNotes
1Regular positional argsdef f(a, b):Fixed positional arguments. Must come before *args.
2Variable positional argsdef f(*args):Accepts any number of positional arguments as a tuple.
3Keyword-only argsdef f(*args, key):Arguments after *args can only be passed as keyword arguments.
4Variable keyword argsdef f(**kwargs):Accepts any number of keyword arguments as a dictionary. Must be last.
-Caller: * unpackingf(*my_list)Expands a list or tuple as positional arguments.
-Caller: ** unpackingf(**my_dict)Expands a dictionary as keyword arguments.

Sample Code

The basics of receiving any number of positional arguments as a tuple with *args.

basic_args.py
# A function that receives a list of PSYCHO-PASS Enforcers using *args.
# Any number of arguments can be received as a tuple.
def list_enforcers(*args):
    print("Enforcer list (" + str(len(args)) + " members)")
    for i, name in enumerate(args, 1):
        print("  " + str(i) + ". " + name)

# Any number of arguments can be passed freely.
list_enforcers("Kogami Shinya")
print("---")
list_enforcers("Kunizuka Yayoi", "Shimomura Mika", "Hinakawa Sho")
print("---")

# The contents of *args is a tuple.
def show_args_type(*args):
    print(type(args), args)

show_args_type("Tsunemori Akane", "Ginoza Nobuchika", "Masaoka Tomomi")
python3 basic_args.py
Enforcer list (1 members)
  1. Kogami Shinya
---
Enforcer list (3 members)
  1. Kunizuka Yayoi
  2. Shimomura Mika
  3. Hinakawa Sho
---
<class 'tuple'> ('Tsunemori Akane', 'Ginoza Nobuchika', 'Masaoka Tomomi')

The basics of receiving any number of keyword arguments as a dictionary with **kwargs.

basic_kwargs.py
# A function that receives an Inspector's profile using **kwargs.
# Key-value pairs are received together as a dictionary.
def show_profile(**kwargs):
    print("Profile information:")
    for key, value in kwargs.items():
        print("  " + key + ": " + str(value))

# The caller can freely decide the keyword names and count.
show_profile(name="Tsunemori Akane", division="Division 1", role="Inspector")
print("---")
show_profile(name="Ginoza Nobuchika", coefficient=99, hue="Clear")

# The contents of **kwargs is a dictionary.
def show_kwargs_type(**kwargs):
    print(type(kwargs), kwargs)

show_kwargs_type(name="Makishima Shogo", status="Wanted")
python3 basic_kwargs.py
Profile information:
  name: Tsunemori Akane
  division: Division 1
  role: Inspector
---
Profile information:
  name: Ginoza Nobuchika
  coefficient: 99
  hue: Clear
<class 'dict'> {'name': 'Makishima Shogo', 'status': 'Wanted'}

Combining regular args, *args, keyword-only args, and **kwargs. The argument order rule must be followed.

combined_args.py
# A function combining multiple argument types.
# Order: regular args -> *args -> keyword-only args -> **kwargs
def register_case(division, *suspects, priority, **details):
    print("[Case Registration]")
    print("  Division: " + division)
    print("  Priority: " + priority)          # keyword-only arg
    print("  Suspects: " + str(suspects))     # tuple
    print("  Details:")
    for key, value in details.items():
        print("    " + key + ": " + str(value))

# division is positional, priority is keyword-only (must pass as keyword)
register_case(
    "Division 1",                             # division (regular positional arg)
    "Makishima Shogo", "Kijima Hiroto",       # *suspects (variable positional args)
    priority="High",                          # keyword-only arg
    area="Shibuya",                           # **details
    weapon="Hyper-Oratrio",
)
python3 combined_args.py
[Case Registration]
  Division: Division 1
  Priority: High
  Suspects: ('Makishima Shogo', 'Kijima Hiroto')
  Details:
    area: Shibuya
    weapon: Hyper-Oratrio

Unpacking with *list and **dict on the caller side.

unpack_call.py
# A function that receives Dominator configuration.
def configure_dominator(user, mode, coefficient):
    print(user + " / Mode: " + mode + " / Coefficient: " + str(coefficient))

# Unpack a list with * and pass as positional arguments.
params = ["Ginoza Nobuchika", "Paralyzer", 180]
configure_dominator(*params)

# Unpack a dict with ** and pass as keyword arguments.
settings = {"user": "Kogami Shinya", "mode": "Lethal Eliminator", "coefficient": 320}
configure_dominator(**settings)

# The same works when passing to a function that accepts *args.
def scan_all(*names):
    for name in names:
        print(name + "'s hue is being scanned...")

officers = ["Tsunemori Akane", "Kunizuka Yayoi", "Shimomura Mika"]
scan_all(*officers)   # each element of the list is expanded as a positional argument.
python3 unpack_call.py
Ginoza Nobuchika / Mode: Paralyzer / Coefficient: 180
Kogami Shinya / Mode: Lethal Eliminator / Coefficient: 320
Tsunemori Akane's hue is being scanned...
Kunizuka Yayoi's hue is being scanned...
Shimomura Mika's hue is being scanned...

Common Mistakes

Common Mistake 1: Reversed order of *args and **kwargs causes SyntaxError

Writing **kwargs before *args causes a SyntaxError. The correct order is: regular args → *args → keyword-only args → **kwargs.

ng_order.py
# NG: writing **kwargs before *args causes a SyntaxError.
def show_info(**kwargs, *args):
    pass
python3 ng_order.py
  File "ng_order.py", line 2
    def show_info(**kwargs, *args):
                            ^
SyntaxError: arguments cannot follow var-keyword argument
ok_order.py
# OK: write in order: regular args -> *args -> **kwargs.
def show_info(*args, **kwargs):
    print("args:", args)
    print("kwargs:", kwargs)

show_info("Kogami Shinya", "Tsunemori Akane", division="Division 1", role="Inspector")
python3 ok_order.py
args: ('Kogami Shinya', 'Tsunemori Akane')
kwargs: {'division': 'Division 1', 'role': 'Inspector'}

Common Mistake 2: Mixing default-value args with *args

Default-value arguments must be written before *args. Arguments with default values written after *args become keyword-only arguments. Attempting to pass them as positional arguments causes them to be absorbed by *args.

ng_default_args.py
# NG: a default-value argument after *args cannot be passed positionally.
def register(*names, division="Unknown"):
    for name in names:
        print(name, "->", division)

# Passing division without a keyword causes it to be absorbed into *names.
register("Kunizuka Yayoi", "Shimomura Mika", "Division 1")   # "Division 1" ends up in names.
python3 ng_default_args.py
Kunizuka Yayoi -> Unknown
Shimomura Mika -> Unknown
Division 1 -> Unknown
ok_default_args.py
# OK: pass arguments after *args using keywords.
def register(*names, division="Unknown"):
    for name in names:
        print(name, "->", division)

register("Kunizuka Yayoi", "Shimomura Mika", division="Division 1")
python3 ok_default_args.py
Kunizuka Yayoi -> Division 1
Shimomura Mika -> Division 1

Common Mistake 3: Passing the same key twice to **kwargs causes SyntaxError

Passing the same key name twice to **kwargs causes a SyntaxError. The same issue occurs when a dict unpacking and a normal keyword argument share the same name.

ng_duplicate_key.py
# NG: passing the same key twice causes a SyntaxError.
def show_profile(**kwargs):
    print(kwargs)

# Writing the same keyword argument twice causes SyntaxError.
show_profile(name="Tsunemori Akane", name="Ginoza Nobuchika")
python3 ng_duplicate_key.py
  File "ng_duplicate_key.py", line 6
    show_profile(name="Tsunemori Akane", name="Ginoza Nobuchika")
                                         ^^^^
SyntaxError: keyword argument repeated: name
ok_duplicate_key.py
# OK: make sure keys do not duplicate.
def show_profile(**kwargs):
    print(kwargs)

show_profile(name="Tsunemori Akane", division="Division 1", role="Inspector")
python3 ok_duplicate_key.py
{'name': 'Tsunemori Akane', 'division': 'Division 1', 'role': 'Inspector'}

Notes

The names args and kwargs themselves have no special meaning — the * and ** symbols are what matter. They are simply widely used by convention, so *values or **options works just as well. The convention of using *args and **kwargs has become established for readability.

Violating the argument order rules causes a SyntaxError. The correct order is: regular positional args → *args → keyword-only args → **kwargs. Arguments written after *args automatically become keyword-only, meaning the caller must always pass them by keyword. This property can also be used by writing just * without *args as a separator for keyword-only arguments (see def / Function Definition).

The * and ** unpacking on the caller side allows passing parameters stored in lists or dicts directly to functions, making them useful for passing configuration data and implementing wrapper functions. The pattern of forwarding received **kwargs to another function using **kwargs is also frequently seen in decorator implementations.

If you find any errors or copyright issues, please .