Skip to content

Commit da2996b

Browse files
committed
added args and kwargs
1 parent bb99768 commit da2996b

File tree

2 files changed

+544
-0
lines changed

2 files changed

+544
-0
lines changed
Lines changed: 272 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,272 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"metadata": {},
6+
"source": [
7+
"# `*args` and `**kwargs`\n",
8+
"\n",
9+
"Work with Python long enough, and eventually you will encounter `*args` and `**kwargs`. These strange terms show up as parameters in function definitions. What do they do? Let's review a simple function:"
10+
]
11+
},
12+
{
13+
"cell_type": "code",
14+
"execution_count": 1,
15+
"metadata": {},
16+
"outputs": [
17+
{
18+
"data": {
19+
"text/plain": [
20+
"5.0"
21+
]
22+
},
23+
"execution_count": 1,
24+
"metadata": {},
25+
"output_type": "execute_result"
26+
}
27+
],
28+
"source": [
29+
"def myfunc(a,b):\n",
30+
" return sum((a,b))*.05\n",
31+
"\n",
32+
"myfunc(40,60)"
33+
]
34+
},
35+
{
36+
"cell_type": "markdown",
37+
"metadata": {},
38+
"source": [
39+
"This function returns 5% of the sum of **a** and **b**. In this example, **a** and **b** are *positional* arguments; that is, 40 is assigned to **a** because it is the first argument, and 60 to **b**. Notice also that to work with multiple positional arguments in the `sum()` function we had to pass them in as a tuple.\n",
40+
"\n",
41+
"What if we want to work with more than two numbers? One way would be to assign a *lot* of parameters, and give each one a default value."
42+
]
43+
},
44+
{
45+
"cell_type": "code",
46+
"execution_count": 2,
47+
"metadata": {},
48+
"outputs": [
49+
{
50+
"data": {
51+
"text/plain": [
52+
"6.0"
53+
]
54+
},
55+
"execution_count": 2,
56+
"metadata": {},
57+
"output_type": "execute_result"
58+
}
59+
],
60+
"source": [
61+
"def myfunc(a=0,b=0,c=0,d=0,e=0):\n",
62+
" return sum((a,b,c,d,e))*.05\n",
63+
"\n",
64+
"myfunc(40,60,20)"
65+
]
66+
},
67+
{
68+
"cell_type": "markdown",
69+
"metadata": {},
70+
"source": [
71+
"Obviously this is not a very efficient solution, and that's where `*args` comes in.\n",
72+
"\n",
73+
"## `*args`\n",
74+
"\n",
75+
"When a function parameter starts with an asterisk, it allows for an *arbitrary number* of arguments, and the function takes them in as a tuple of values. Rewriting the above function:"
76+
]
77+
},
78+
{
79+
"cell_type": "code",
80+
"execution_count": 3,
81+
"metadata": {},
82+
"outputs": [
83+
{
84+
"data": {
85+
"text/plain": [
86+
"6.0"
87+
]
88+
},
89+
"execution_count": 3,
90+
"metadata": {},
91+
"output_type": "execute_result"
92+
}
93+
],
94+
"source": [
95+
"def myfunc(*args):\n",
96+
" return sum(args)*.05\n",
97+
"\n",
98+
"myfunc(40,60,20)"
99+
]
100+
},
101+
{
102+
"cell_type": "markdown",
103+
"metadata": {},
104+
"source": [
105+
"Notice how passing the keyword \"args\" into the `sum()` function did the same thing as a tuple of arguments.\n",
106+
"\n",
107+
"It is worth noting that the word \"args\" is itself arbitrary - any word will do so long as it's preceded by an asterisk. To demonstrate this:"
108+
]
109+
},
110+
{
111+
"cell_type": "code",
112+
"execution_count": 4,
113+
"metadata": {},
114+
"outputs": [
115+
{
116+
"data": {
117+
"text/plain": [
118+
"6.0"
119+
]
120+
},
121+
"execution_count": 4,
122+
"metadata": {},
123+
"output_type": "execute_result"
124+
}
125+
],
126+
"source": [
127+
"def myfunc(*spam):\n",
128+
" return sum(spam)*.05\n",
129+
"\n",
130+
"myfunc(40,60,20)"
131+
]
132+
},
133+
{
134+
"cell_type": "markdown",
135+
"metadata": {},
136+
"source": [
137+
"## `**kwargs`\n",
138+
"\n",
139+
"Similarly, Python offers a way to handle arbitrary numbers of *keyworded* arguments. Instead of creating a tuple of values, `**kwargs` builds a dictionary of key/value pairs. For example:"
140+
]
141+
},
142+
{
143+
"cell_type": "code",
144+
"execution_count": 5,
145+
"metadata": {},
146+
"outputs": [
147+
{
148+
"name": "stdout",
149+
"output_type": "stream",
150+
"text": [
151+
"My favorite fruit is pineapple\n"
152+
]
153+
}
154+
],
155+
"source": [
156+
"def myfunc(**kwargs):\n",
157+
" if 'fruit' in kwargs:\n",
158+
" print(f\"My favorite fruit is {kwargs['fruit']}\") # review String Formatting and f-strings if this syntax is unfamiliar\n",
159+
" else:\n",
160+
" print(\"I don't like fruit\")\n",
161+
" \n",
162+
"myfunc(fruit='pineapple')"
163+
]
164+
},
165+
{
166+
"cell_type": "code",
167+
"execution_count": 6,
168+
"metadata": {},
169+
"outputs": [
170+
{
171+
"name": "stdout",
172+
"output_type": "stream",
173+
"text": [
174+
"I don't like fruit\n"
175+
]
176+
}
177+
],
178+
"source": [
179+
"myfunc()"
180+
]
181+
},
182+
{
183+
"cell_type": "markdown",
184+
"metadata": {},
185+
"source": [
186+
"## `*args` and `**kwargs` combined\n",
187+
"\n",
188+
"You can pass `*args` and `**kwargs` into the same function, but `*args` have to appear before `**kwargs`"
189+
]
190+
},
191+
{
192+
"cell_type": "code",
193+
"execution_count": 7,
194+
"metadata": {},
195+
"outputs": [
196+
{
197+
"name": "stdout",
198+
"output_type": "stream",
199+
"text": [
200+
"I like eggs and spam and my favorite fruit is cherries\n",
201+
"May I have some orange juice?\n"
202+
]
203+
}
204+
],
205+
"source": [
206+
"def myfunc(*args, **kwargs):\n",
207+
" if 'fruit' and 'juice' in kwargs:\n",
208+
" print(f\"I like {' and '.join(args)} and my favorite fruit is {kwargs['fruit']}\")\n",
209+
" print(f\"May I have some {kwargs['juice']} juice?\")\n",
210+
" else:\n",
211+
" pass\n",
212+
" \n",
213+
"myfunc('eggs','spam',fruit='cherries',juice='orange')"
214+
]
215+
},
216+
{
217+
"cell_type": "markdown",
218+
"metadata": {},
219+
"source": [
220+
"Placing keyworded arguments ahead of positional arguments raises an exception:"
221+
]
222+
},
223+
{
224+
"cell_type": "code",
225+
"execution_count": 8,
226+
"metadata": {},
227+
"outputs": [
228+
{
229+
"ename": "SyntaxError",
230+
"evalue": "positional argument follows keyword argument (<ipython-input-8-fc6ff65addcc>, line 1)",
231+
"output_type": "error",
232+
"traceback": [
233+
"\u001b[1;36m File \u001b[1;32m\"<ipython-input-8-fc6ff65addcc>\"\u001b[1;36m, line \u001b[1;32m1\u001b[0m\n\u001b[1;33m myfunc(fruit='cherries',juice='orange','eggs','spam')\u001b[0m\n\u001b[1;37m ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m positional argument follows keyword argument\n"
234+
]
235+
}
236+
],
237+
"source": [
238+
"myfunc(fruit='cherries',juice='orange','eggs','spam')"
239+
]
240+
},
241+
{
242+
"cell_type": "markdown",
243+
"metadata": {},
244+
"source": [
245+
"As with \"args\", you can use any name you'd like for keyworded arguments - \"kwargs\" is just a popular convention.\n",
246+
"\n",
247+
"That's it! Now you should understand how `*args` and `**kwargs` provide the flexibilty to work with arbitrary numbers of arguments!"
248+
]
249+
}
250+
],
251+
"metadata": {
252+
"kernelspec": {
253+
"display_name": "Python 3",
254+
"language": "python",
255+
"name": "python3"
256+
},
257+
"language_info": {
258+
"codemirror_mode": {
259+
"name": "ipython",
260+
"version": 3
261+
},
262+
"file_extension": ".py",
263+
"mimetype": "text/x-python",
264+
"name": "python",
265+
"nbconvert_exporter": "python",
266+
"pygments_lexer": "ipython3",
267+
"version": "3.6.2"
268+
}
269+
},
270+
"nbformat": 4,
271+
"nbformat_minor": 2
272+
}

0 commit comments

Comments
 (0)