Chapter 6: Higher order functions

The filter function

face Josiah Wang

Here is another piece of code with list comprehension. What does it do?

>>> numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> even_numbers = [n for n in numbers if n%2 == 0]
>>> print(even_numbers)
[2, 4, 6, 8]

You are essentially filtering the list of numbers to keep only even numbers.

The filter function

An alternative way to accomplish this is to use another built-in higher-order function called filter().

filter(func, iterable) returns only elements in iterable when func returns True for the element. Basically, it filters iterable according to func.

Here is an implementation with filter().

>>> numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> even_numbers = list(filter(lambda n: n%2==0, numbers))
>>> print(even_numbers)
[2, 4, 6, 8]

Exercise 1

You are given a list of words. The following piece of code removes all words in the list that are shorter than 5 characters.

words = ["Oh", "I", "wanna", "dance", "with", "somebody"]
long_words = [word for word in words if len(word) >= 5]
assert long_words == ['wanna', 'dance', 'somebody']

Your task: rewrite this using filter() and lambda functions.

A possible solution:

words = ["Oh", "I", "wanna", "dance", "with", "somebody"]
long_words = list(filter(lambda w: len(w)>=5, words))
assert long_words == ['wanna', 'dance', 'somebody']

Exercise 2

Given numbers = range(100, 300), use filter() and lambda functions to filter numbers to keep only numbers that are palindromes. Remember that a palindrome is a word that reads the same forwards and backwards, e.g. 101 and 262. If you like, also implement a solution with list comprehension to compare.

numbers = range(100, 300)
palindromes = ????
assert palindromes == [101, 111, 121, 131, 141, 151, 161, 171, 181, 191, 202, 212, 222, 232, 242, 252, 262, 272, 282, 292]

A possible solution with filter() and lambda functions:

numbers = range(100, 300)
palindromes = list(filter(lambda n: str(n) == str(n)[::-1], numbers))
assert palindromes == [101, 111, 121, 131, 141, 151, 161, 171, 181, 191, 202, 212, 222, 232, 242, 252, 262, 272, 282, 292]

A possible list comprehension solution:

numbers = range(100, 300)
palindromes = [number for number in numbers if str(number) == str(number)[::-1]]
assert palindromes == [101, 111, 121, 131, 141, 151, 161, 171, 181, 191, 202, 212, 222, 232, 242, 252, 262, 272, 282, 292]