*args and **kwargs Examples
Short, runnable programs that show python *args and **kwargs in action. Read the explanation, press Run, then change the code and try your own ideas. New to the topic? Start with the Python *args and **kwargs lesson.
1A max-style function for any number of words
longest(*words) works like the built-ins you already know. It accepts any number of arguments directly, or a whole list when you unpack it with a star.
def longest(*words):
best = ""
for word in words:
if len(word) > len(best):
best = word
return best
print(longest("tea", "coffee", "milk"))
print(longest("hi"))
print(repr(longest()))
menu = ["soup", "salad", "sandwich"]
print(longest(*menu))Expected outputcoffee
hi
''
sandwich
2HTML attributes from a dictionary
class is a reserved word, so it cannot be written as a keyword argument. Unpacking a dictionary with ** lets you pass it anyway.
def build_tag(name, text="", **attributes):
attrs = "".join(f' {key}="{value}"' for key, value in attributes.items())
return f"<{name}{attrs}>{text}</{name}>"
button_style = {"class": "btn", "id": "save"}
print(build_tag("button", "Save", **button_style))
print(build_tag("a", "Home", href="/", title="Start page"))
print(build_tag("h1", "Welcome"))Expected output<button class="btn" id="save">Save</button>
<a href="/" title="Start page">Home</a>
<h1>Welcome</h1>
3Settings with defaults and overrides
**overrides accepts any option. Two dictionaries can be merged with {**defaults, **overrides}; when a key appears in both, the later one wins.
def make_config(**overrides):
defaults = {"debug": False, "port": 8000, "host": "localhost"}
return {**defaults, **overrides}
print(make_config())
print(make_config(port=9000, debug=True))
user_choice = {"host": "0.0.0.0"}
print(make_config(**user_choice))Expected output{'debug': False, 'port': 8000, 'host': 'localhost'}
{'debug': True, 'port': 9000, 'host': 'localhost'}
{'debug': False, 'port': 8000, 'host': '0.0.0.0'}
4A wrapper that logs every call
call_logged does not care which function it receives or what arguments it takes. It describes the call, then forwards everything with *args and **kwargs.
def call_logged(func, *args, **kwargs):
shown = [repr(a) for a in args] + [f"{k}={v!r}" for k, v in kwargs.items()]
print(f"calling {func.__name__}({', '.join(shown)})")
return func(*args, **kwargs)
print(call_logged(round, 3.14159, ndigits=2))
print(call_logged(sorted, [3, 1, 2], reverse=True))
print(call_logged(max, 4, 9, 2))Expected outputcalling round(3.14159, ndigits=2)
3.14
calling sorted([3, 1, 2], reverse=True)
[3, 2, 1]
calling max(4, 9, 2)
9
5Unpacking into built-in functions
Stars work with every function, including built-ins. print(*names, sep=...) prints a list's items without brackets, and zip(*rows) flips rows into columns.
names = ["Asha", "Ben", "Cara"]
print(*names)
print(*names, sep=", ")
rows = [(1, 2, 3), (4, 5, 6)]
columns = list(zip(*rows))
print(columns)
low, high = 3, 9
print(*range(low, high, 2))Expected outputAsha Ben Cara
Asha, Ben, Cara
[(1, 4), (2, 5), (3, 6)]
3 5 7
6Inspecting what a call received
A small helper that reports how its arguments were sorted into the positional tuple and the keyword dictionary is a good way to check your understanding.
def describe(first, *rest, verbose=False, **options):
print("first:", first)
print("rest:", rest, "| count:", len(rest))
print("verbose:", verbose)
print("options:", sorted(options))
describe("a", "b", "c", verbose=True, color="red", size=3)
print("---")
describe("only")Expected outputfirst: a
rest: ('b', 'c') | count: 2
verbose: True
options: ['color', 'size']
---
first: only
rest: () | count: 0
verbose: False
options: []
Practise next
Python *args and **kwargs exercises → Back to the lesson
Python Unpacking examplesPython Dictionaries examplesPython Function Arguments examplesPython Decorators examples