Skip to content

Commit f8c45ae

Browse files
authored
Merge pull request #561 from realpython/functional-programming
Add materials for functional programming update
2 parents 38c65c0 + 363e7d3 commit f8c45ae

File tree

11 files changed

+355
-0
lines changed

11 files changed

+355
-0
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Functional Programming in Python: When and How to Use It
2+
3+
This folder contains the sample code used in the RealPython tutorial [Functional Programming in Python: When and How to Use It](https://realpython.com/python-functional-programming/).
4+
5+
## Run the Scrips
6+
7+
You can run the individual files as Python scripts:
8+
9+
```sh
10+
$ python file_name.py
11+
```
12+
13+
You'll see some output printed to your terminal.
14+
15+
For more context, please read the associated tutorial.
16+
17+
## About the Author
18+
19+
Martin Breuss - Email: [email protected]
20+
21+
## License
22+
23+
Distributed under the MIT license. See ``LICENSE`` for more information.
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
"""
2+
Example use cases of Python's `filter()` function.
3+
"""
4+
5+
6+
# Keep only high numbers.
7+
def greater_than_100(x):
8+
return x > 100
9+
10+
11+
print(list(filter(greater_than_100, [1, 111, 2, 222, 3, 333])))
12+
print(list(filter(lambda x: x > 100, [1, 111, 2, 222, 3, 333])))
13+
14+
15+
# Filter out odd numbers.
16+
def is_even(x):
17+
return x % 2 == 0
18+
19+
20+
print(list(filter(is_even, range(10))))
21+
print(list(filter(lambda x: x % 2 == 0, range(10))))
22+
23+
# Keep only uppercase strings.
24+
animals = ["cat", "Cat", "CAT", "dog", "Dog", "DOG", "emu", "Emu", "EMU"]
25+
26+
27+
def all_caps(s):
28+
return s.isupper()
29+
30+
31+
print(list(filter(all_caps, animals)))
32+
print(list(filter(lambda s: s.isupper(), animals)))
33+
34+
# Remove empty strings.
35+
animals_and_empty_strings = ["", "cat", "dog", "", ""]
36+
37+
print(list(filter(lambda s: s, animals_and_empty_strings)))
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
"""
2+
Example of a nested function scope.
3+
"""
4+
5+
6+
def outer():
7+
def inner():
8+
print("I am function inner()!")
9+
10+
# Function outer() returns function inner().
11+
return inner
12+
13+
14+
function = outer()
15+
16+
print(function)
17+
print(function())
18+
print(outer()())
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
"""
2+
Examples of using a function object as an argument.
3+
"""
4+
5+
animals = ["ferret", "vole", "dog", "gecko"]
6+
print(sorted(animals))
7+
8+
animals = ["ferret", "vole", "dog", "gecko"]
9+
print(sorted(animals, key=len))
10+
11+
animals = ["ferret", "vole", "dog", "gecko"]
12+
print(sorted(animals, key=len, reverse=True))
13+
14+
15+
def reverse_len(s):
16+
return -len(s)
17+
18+
19+
print(sorted(animals, key=reverse_len))
20+
21+
# Using a lambda expression
22+
sorted(animals, key=lambda s: -len(s))
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
"""
2+
Examples of using functions as objects.
3+
"""
4+
5+
6+
# Call a function.
7+
def func():
8+
print("I am function func()!")
9+
10+
11+
print(func())
12+
13+
14+
# Assign it to a new name.
15+
another_name = func
16+
another_name()
17+
18+
# Show a string representation of a function object.
19+
print("cat", func, 42)
20+
21+
# Access a function object in a list.
22+
objects = ["cat", func, 42]
23+
objects[1]
24+
25+
print(objects[1]())
26+
27+
# Use a function object as a key in a dictionary.
28+
# Note that this is probably not a good idea.
29+
d = {"cat": 1, func: 2, 42: 3}
30+
print(d[func])
31+
32+
33+
# Pass a function as an argument.
34+
def inner():
35+
print("I am function inner()!")
36+
37+
38+
def outer(function):
39+
function()
40+
41+
42+
print(outer(inner))
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
"""
2+
Example implementations of using `reduce()` to create
3+
functional versions of `map()` and `filter()`.
4+
"""
5+
6+
# Compare `map()` to `custom_map()`.
7+
numbers = [1, 2, 3, 4, 5]
8+
9+
print(list(map(str, numbers)))
10+
11+
12+
def custom_map(function, iterable):
13+
from functools import reduce
14+
15+
return reduce(
16+
lambda items, value: items + [function(value)],
17+
iterable,
18+
[],
19+
)
20+
21+
22+
print(list(custom_map(str, numbers)))
23+
24+
25+
# Compare `filter()` to `custom_filter()`.
26+
numbers = list(range(10))
27+
28+
29+
def is_even(x):
30+
return x % 2 == 0
31+
32+
33+
print(list(filter(is_even, numbers)))
34+
35+
36+
def custom_filter(function, iterable):
37+
from functools import reduce
38+
39+
return reduce(
40+
lambda items, value: items + [value] if function(value) else items,
41+
iterable,
42+
[],
43+
)
44+
45+
46+
print(list(custom_filter(is_even, numbers)))
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
"""
2+
Examples of writing lambda expressions.
3+
"""
4+
5+
6+
# Reverse a string.
7+
def reverse(s):
8+
return s[::-1]
9+
10+
11+
reverse("I am a string")
12+
13+
14+
reverse = lambda s: s[::-1] # noqa E731
15+
print(reverse("I am a string"))
16+
17+
print((lambda s: s[::-1])("I am a string"))
18+
19+
20+
# Calculate the average of three numbers.
21+
print((lambda x1, x2, x3: (x1 + x2 + x3) / 3)(9, 6, 6))
22+
print((lambda x1, x2, x3: (x1 + x2 + x3) / 3)(1.4, 1.1, 0.5))
23+
24+
# Return a fixed value.
25+
forty_two_producer = lambda: 42 # noqa E731
26+
print(forty_two_producer())
27+
28+
# Use a conditional expression.
29+
print((lambda x: "even" if x % 2 == 0 else "odd")(2))
30+
print((lambda x: "even" if x % 2 == 0 else "odd")(3))
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
"""
2+
Example of using multiple iterables as arguments to `map()`.
3+
"""
4+
5+
6+
def add_three(a, b, c):
7+
return a + b + c
8+
9+
10+
print(list(map(add_three, [1, 2, 3], [10, 20, 30], [100, 200, 300])))
11+
12+
# Using a lambda expression.
13+
print(
14+
list(
15+
map(
16+
(lambda a, b, c: a + b + c),
17+
[1, 2, 3],
18+
[10, 20, 30],
19+
[100, 200, 300],
20+
)
21+
)
22+
)
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
"""
2+
Examples of using `map()` with a single iterable.
3+
"""
4+
5+
6+
def reverse(s):
7+
return s[::-1]
8+
9+
10+
print(reverse("I am a string"))
11+
12+
animals = ["cat", "dog", "hedgehog", "gecko"]
13+
14+
# Use `map()` to create an iterator.
15+
iterator = map(reverse, animals)
16+
print(iterator)
17+
18+
# Consume the iterator with a for loop.
19+
iterator = map(reverse, animals)
20+
for i in iterator:
21+
print(i)
22+
23+
# Consume the iterator with a call to `list()`.
24+
iterator = map(reverse, animals)
25+
print(list(iterator))
26+
27+
28+
# Use a lambda expression.
29+
iterator = map(lambda s: s[::-1], animals)
30+
print(list(iterator))
31+
32+
33+
# All the code in a single line.
34+
print(list(map(lambda s: s[::-1], ["cat", "dog", "hedgehog", "gecko"])))
35+
36+
# Convert integers to strings before concatenating them.
37+
print("+".join(map(str, [1, 2, 3, 4, 5])))
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
"""
2+
Examples of using `reduce()` with an initializer value.
3+
"""
4+
5+
from functools import reduce
6+
7+
8+
def add_two_values(x, y):
9+
return x + y
10+
11+
12+
# Initialize with the value `100`.
13+
# (100 + 1 + 2 + 3 + 4 + 5)
14+
print(reduce(add_two_values, [1, 2, 3, 4, 5], 100))
15+
16+
# Use a lambda expression.
17+
print(reduce(lambda x, y: x + y, [1, 2, 3, 4, 5], 100))
18+
19+
# Use `sum()` and add a value instead.
20+
print(100 + sum([1, 2, 3, 4, 5]))

0 commit comments

Comments
 (0)