avatarJonathan Hsu

Free AI web copilot to create summaries, insights and extended knowledge, download it at here

3349

Abstract

printThese(<span class="hljs-number">1</span>,<span class="hljs-number">2</span>) <span class="hljs-string">""" 1 is stored in a 2 is stored in b None is stored in c """</span></pre></div><p id="5e9b">Additionally, these optional parameters also become keyword-eligible, meaning you can specify the parameter name in the function call to map it accordingly.</p><p id="f1a3">Let’s make all three variables default to <code>None</code> and watch how we can still map them irregardless of order.</p><div id="b76a"><pre><span class="hljs-keyword">def</span> <span class="hljs-title function_">printThese</span>(<span class="hljs-params">a=<span class="hljs-literal">None</span>,b=<span class="hljs-literal">None</span>,c=<span class="hljs-literal">None</span></span>): <span class="hljs-built_in">print</span>(a, <span class="hljs-string">"is stored in a"</span>) <span class="hljs-built_in">print</span>(b, <span class="hljs-string">"is stored in b"</span>) <span class="hljs-built_in">print</span>(c, <span class="hljs-string">"is stored in c"</span>)</pre></div><div id="3b8f"><pre><span class="hljs-built_in">printThese</span>(c=<span class="hljs-number">3</span>, a=<span class="hljs-number">1</span>) """ def <span class="hljs-built_in">printThese</span>(a=None,b=None,c=None): <span class="hljs-built_in">print</span>(a, <span class="hljs-string">"is stored in a"</span>) <span class="hljs-built_in">print</span>(b, <span class="hljs-string">"is stored in b"</span>) <span class="hljs-built_in">print</span>(c, <span class="hljs-string">"is stored in c"</span>)</pre></div><div id="2b3b"><pre>printThese(c=<span class="hljs-number">3</span>, a=<span class="hljs-number">1</span>) <span class="hljs-string">""" 1 is stored in a None is stored in b 3 is stored in c """</span></pre></div><h1 id="3e00">The Splat Operator</h1><p id="23fd">Let me start by saying I love the name of this operator — it’s so … visual. The <code>*</code> is most commonly associated with multiplication, but in Python it doubles as the splat operator.</p><p id="fa80">I think of this operator as a piñata. I’ve described the spread operator — the JavaScript equivalent of splat — as unpacking a series of dominoes to form a single larger sequence, but splat warrants a more forceful analogy.</p><p id="dc69">A simple example will make this more clear.</p><div id="172a"><pre><span class="hljs-attr">a</span> = [<span class="hljs-number">1</span>,<span class="hljs-number">2</span>,<span class="hljs-number">3</span>] <span class="hljs-attr">b</span> = [*a,<span class="hljs-number">4</span>,<span class="hljs-number">5</span>,<span class="hljs-number">6</span>]</pre></div><div id="50a2"><pre><span class="hljs-built_in">print</span>(b) # <span class="hljs-selector-attr">[1,2,3,4,5,6]</span></pre></div><p id="6291">In the code example, we’re taking the contents of <code>a</code> and splattering (unpacking) it into our new list <code>b</code>.</p><h1 id="fda0">How To Use *args and **kwargs</h1><p id="9ed1">So we know the splat operator unpacks multiple values, and there are two types of function parameters. Well, if you haven’t figured it out by now, <code>*args</code> is short for arguments, and <code>**kwargs</code> is short for keyword arguments.</p><p id="1805">Each is used to unpack their respective argument type, allowing for function

Options

calls with variable-length argument lists. For example, let’s create a function to print a student’s test scores.</p><div id="edb5"><pre><span class="hljs-keyword">def</span> <span class="hljs-title function_">printScores</span>(<span class="hljs-params">student, *scores</span>): <span class="hljs-built_in">print</span>(<span class="hljs-string">f"Student Name: <span class="hljs-subst">{student}</span>"</span>) <span class="hljs-keyword">for</span> score <span class="hljs-keyword">in</span> scores: <span class="hljs-built_in">print</span>(score)</pre></div><div id="4e63"><pre>printScores(<span class="hljs-string">"Jonathan"</span>,<span class="hljs-number">100</span>, <span class="hljs-number">95</span>, <span class="hljs-number">88</span>, <span class="hljs-number">92</span>, <span class="hljs-number">99</span>) <span class="hljs-string">""" Student Name: Jonathan 100 95 88 92 99 """</span></pre></div><p id="0d11">Whoa, wait. I didn’t name it <code>*args</code>? That’s right, “args” is a standard convention but still just a name. The secret revealed, in <code>*args</code>, the single asterisk is the real player here, creating a list whose contents are positional arguments — after those defined — from the function call.</p><p id="12c8">With that cleared up, <code>**kwargs</code> should be a easy to digest. The name doesn’t matter, but the double asterisks create a dictionary whose contents are keyword arguments — after those defined — from a function call.</p><p id="842b">To illustrate this, let’s create a function to print the names of a person’s pets.</p><div id="c2b0"><pre><span class="hljs-keyword">def</span> <span class="hljs-title function_">printPetNames</span>(<span class="hljs-params">owner, **pets</span>): <span class="hljs-built_in">print</span>(<span class="hljs-string">f"Owner Name: <span class="hljs-subst">{owner}</span>"</span>) <span class="hljs-keyword">for</span> pet,name <span class="hljs-keyword">in</span> pets.items(): <span class="hljs-built_in">print</span>(<span class="hljs-string">f"<span class="hljs-subst">{pet}</span>: <span class="hljs-subst">{name}</span>"</span>)</pre></div><div id="b542"><pre>printPetNames(<span class="hljs-string">"Jonathan"</span>, <span class="hljs-attribute">dog</span>=<span class="hljs-string">"Brock"</span>, fish=[<span class="hljs-string">"Larry"</span>, <span class="hljs-string">"Curly"</span>, <span class="hljs-string">"Moe"</span>], <span class="hljs-attribute">turtle</span>=<span class="hljs-string">"Shelldon"</span>)</pre></div><div id="e40c"><pre><span class="hljs-string">""" Owner Name: Jonathan dog: Brock fish: ['Larry', 'Curly', 'Moe'] turtle: Shelldon """</span></pre></div><h1 id="9df8">Parting Words</h1><p id="f571">A few words of wisdom to help you avoid common pitfalls and expand your knowledge.</p><ul><li>Use <code>*args,</code> <code>**kwargs</code> as a standard convention to catch positional and keyword arguments</li><li>You cannot place <code>**kwargs</code> before <code>*args</code>, or you’ll receive an error</li><li>Beware of conflicts between keyword parameters and <code>**kwargs</code> where the value is meant to be passed as a <code>**kwarg</code> but is unknowingly the name of a keyword parameter</li><li>You can use the splat operator in function calls as well</li></ul></article></body>

What Are *args and **kwargs in Python?

Learn to use variable-length argument lists

Photo by Headway on Unsplash

Functions are life, right? If you’re new to Python — whether brand new to coding or coming from another language — you learn the number of parameters in a function’s definition match the number of arguments meant to be passed.

This is foundational — it helps make sense of the world. However, it also sets you up for early mental stumbling blocks as soon as you see *args or **kwargs in a function definition.

Don’t let the syntax scare you. These aren’t super special parameters. They’re not even that fancy, and we’re going to learn how to use them.

Positional vs. Keyword Arguments

There are two concepts we need to separate in order to learn what *args and **kwargs are.

The first is the difference between positional and keyword arguments. In the most basic of functions, we play a matching game — argument 1 goes with parameter 1, argument 2 goes with parameter 2, and so on.

def printThese(a,b,c):
   print(a, "is stored in a")
   print(b, "is stored in b")
   print(c, "is stored in c")
printThese(1,2,3)
"""
1 is stored in a
2 is stored in b
3 is stored in c
"""

All three arguments are required. Missing one will cause an error.

def printThese(a,b,c):
   print(a, "is stored in a")
   print(b, "is stored in b")
   print(c, "is stored in c")
printThese(1,2)
"""
TypeError: printThese() missing 1 required positional argument: 'c'
"""

If we give a parameter a default value in the function definition, then it becomes optional.

def printThese(a,b,c=None):
   print(a, "is stored in a")
   print(b, "is stored in b")
   print(c, "is stored in c")
printThese(1,2)
"""
1 is stored in a
2 is stored in b
None is stored in c
"""

Additionally, these optional parameters also become keyword-eligible, meaning you can specify the parameter name in the function call to map it accordingly.

Let’s make all three variables default to None and watch how we can still map them irregardless of order.

def printThese(a=None,b=None,c=None):
   print(a, "is stored in a")
   print(b, "is stored in b")
   print(c, "is stored in c")
printThese(c=3, a=1)
"""
def printThese(a=None,b=None,c=None):
   print(a, "is stored in a")
   print(b, "is stored in b")
   print(c, "is stored in c")
printThese(c=3, a=1)
"""
1 is stored in a
None is stored in b
3 is stored in c
"""

The Splat Operator

Let me start by saying I love the name of this operator — it’s so … visual. The * is most commonly associated with multiplication, but in Python it doubles as the splat operator.

I think of this operator as a piñata. I’ve described the spread operator — the JavaScript equivalent of splat — as unpacking a series of dominoes to form a single larger sequence, but splat warrants a more forceful analogy.

A simple example will make this more clear.

a = [1,2,3]
b = [*a,4,5,6]
print(b) # [1,2,3,4,5,6]

In the code example, we’re taking the contents of a and splattering (unpacking) it into our new list b.

How To Use *args and **kwargs

So we know the splat operator unpacks multiple values, and there are two types of function parameters. Well, if you haven’t figured it out by now, *args is short for arguments, and **kwargs is short for keyword arguments.

Each is used to unpack their respective argument type, allowing for function calls with variable-length argument lists. For example, let’s create a function to print a student’s test scores.

def printScores(student, *scores):
   print(f"Student Name: {student}")
   for score in scores:
      print(score)
printScores("Jonathan",100, 95, 88, 92, 99)
"""
Student Name: Jonathan
100
95
88
92
99
"""

Whoa, wait. I didn’t name it *args? That’s right, “args” is a standard convention but still just a name. The secret revealed, in *args, the single asterisk is the real player here, creating a list whose contents are positional arguments — after those defined — from the function call.

With that cleared up, **kwargs should be a easy to digest. The name doesn’t matter, but the double asterisks create a dictionary whose contents are keyword arguments — after those defined — from a function call.

To illustrate this, let’s create a function to print the names of a person’s pets.

def printPetNames(owner, **pets):
   print(f"Owner Name: {owner}")
   for pet,name in pets.items():
      print(f"{pet}: {name}")
printPetNames("Jonathan", dog="Brock", fish=["Larry", "Curly", "Moe"], turtle="Shelldon")
"""
Owner Name: Jonathan
dog: Brock
fish: ['Larry', 'Curly', 'Moe']
turtle: Shelldon
"""

Parting Words

A few words of wisdom to help you avoid common pitfalls and expand your knowledge.

  • Use *args, **kwargs as a standard convention to catch positional and keyword arguments
  • You cannot place **kwargs before *args, or you’ll receive an error
  • Beware of conflicts between keyword parameters and **kwargs where the value is meant to be passed as a **kwarg but is unknowingly the name of a keyword parameter
  • You can use the splat operator in function calls as well
Python
Programming
Software Development
Data Science
Technology
Recommended from ReadMedium