Skip to content

Commit 631a0b3

Browse files
committed
Add section on attrgetter and itemgetter
1 parent d737fb3 commit 631a0b3

File tree

1 file changed

+113
-2
lines changed

1 file changed

+113
-2
lines changed

source-code/functional-programming/functional_programming_style.ipynb

Lines changed: 113 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,14 @@
99
},
1010
{
1111
"cell_type": "code",
12-
"execution_count": 5,
12+
"execution_count": 30,
1313
"metadata": {},
1414
"outputs": [],
1515
"source": [
1616
"from collections import Counter\n",
17+
"from dataclasses import dataclass\n",
1718
"from functools import reduce, partial\n",
19+
"from operator import attrgetter, itemgetter\n",
1820
"import random"
1921
]
2022
},
@@ -225,6 +227,114 @@
225227
" counter[x] += 1"
226228
]
227229
},
230+
{
231+
"cell_type": "markdown",
232+
"metadata": {},
233+
"source": [
234+
"## Convenience functions"
235+
]
236+
},
237+
{
238+
"cell_type": "markdown",
239+
"metadata": {},
240+
"source": [
241+
"When using the `map` function, a common tasks is to do a computation involving a specific object attribute. Consider the data class `Person`. You would like to compute the average age of people in a list."
242+
]
243+
},
244+
{
245+
"cell_type": "code",
246+
"execution_count": 28,
247+
"metadata": {},
248+
"outputs": [],
249+
"source": [
250+
"@dataclass\n",
251+
"class Person:\n",
252+
" firstname: str\n",
253+
" lastname: str\n",
254+
" age: int"
255+
]
256+
},
257+
{
258+
"cell_type": "code",
259+
"execution_count": 29,
260+
"metadata": {},
261+
"outputs": [],
262+
"source": [
263+
"people = [\n",
264+
" Person('Alice', 'Wonderland', 12),\n",
265+
" Person('Bob', 'Ludlum', 68),\n",
266+
" Person('Carol', 'Christmas', 38),\n",
267+
"]"
268+
]
269+
},
270+
{
271+
"cell_type": "markdown",
272+
"metadata": {},
273+
"source": [
274+
"For each person in the list, the age has to be extracted. This can easily be done using a lambda function."
275+
]
276+
},
277+
{
278+
"cell_type": "code",
279+
"execution_count": 31,
280+
"metadata": {},
281+
"outputs": [
282+
{
283+
"data": {
284+
"text/plain": [
285+
"39.333333333333336"
286+
]
287+
},
288+
"execution_count": 31,
289+
"metadata": {},
290+
"output_type": "execute_result"
291+
}
292+
],
293+
"source": [
294+
"sum(map(lambda p: p.age, people))/len(people)"
295+
]
296+
},
297+
{
298+
"cell_type": "markdown",
299+
"metadata": {},
300+
"source": [
301+
"However, this is such a common pattern that the Python standard library has a function for it. This function also has the advantage that the attribute to be extracted is specified as a string, and hcnce can be computed."
302+
]
303+
},
304+
{
305+
"cell_type": "code",
306+
"execution_count": 32,
307+
"metadata": {},
308+
"outputs": [
309+
{
310+
"data": {
311+
"text/plain": [
312+
"39.333333333333336"
313+
]
314+
},
315+
"execution_count": 32,
316+
"metadata": {},
317+
"output_type": "execute_result"
318+
}
319+
],
320+
"source": [
321+
"sum(map(attrgetter('age'), people))/len(people)"
322+
]
323+
},
324+
{
325+
"cell_type": "markdown",
326+
"metadata": {},
327+
"source": [
328+
"Similar to `attrgetter`, the function `itemgetter` can be used to extract an element of a tuple or a list by index."
329+
]
330+
},
331+
{
332+
"cell_type": "markdown",
333+
"metadata": {},
334+
"source": [
335+
"Note that `attrgetter` and `itemgetter` return a callable, so they are examples of higher-order functions."
336+
]
337+
},
228338
{
229339
"cell_type": "markdown",
230340
"metadata": {},
@@ -497,7 +607,8 @@
497607
"nbconvert_exporter": "python",
498608
"pygments_lexer": "ipython3",
499609
"version": "3.9.5"
500-
}
610+
},
611+
"toc-autonumbering": true
501612
},
502613
"nbformat": 4,
503614
"nbformat_minor": 4

0 commit comments

Comments
 (0)