The Filter Method
The filter()
method is a way to filter through an iterable, using a boolean function as a sieve. It constructs a new iterable, filled with the elements from the original iterable that pass the criterion of your boolean function.
It’s a quick, easy way to test every element in your iterable against a certain criterion – those that pass are passed on to the output, those that fail are left out.
Exercise 5: Make a custom filter
I’ve found that making my own versions of built-in methods helps me understand the built-in methods a lot better. You should try to do it:
Instructions
- Build a function called
my_filter
that takes a boolean function and a list as parameters. Themy_filter
function should iterate over the list, and test each element in the list against the boolean function. Elements for which the boolean expression isTrue
should be added to a new list. The function should return the new list.
Once you’ve done that:
- Make a list of numbers:
numbers = range(1, 100)
-
Print the result of calling
my_filter
with a lambda function that filters the elements innumbers
which are divisible by two. - Here’s my solution
Exercise 6
Take this list of tuples:
members = [('name1', 'Reed'), ('song1', "Don't Turn Around"), ('name2', 'Jonathan'), ('song2', "All That She Wants")]
Use your my_filter
method to build a list containing only the tuples that represent the members’ names.
Hints:
- Elements in tuples can be accessed with index references
- The
startswith()
method is super useful here. It takes a string as an argument, and compares that string against the start of the string on which it was called. If the characters all match, it returnsTrue
, otherwise it returnsFalse
. - My solution
The built-in filter()
method
filter(function, iterable)
Now that you’ve got a working version of your custom filter method, let’s look briefly at the advantages of the built-in method.
Advantage 1
From the documentation
If iterable is a string or a tuple, the result also has that type; otherwise it is always a list.
Our function always filters the iterable’s elements into a list. If you filter a tuple or a string, though, the output should be the same.
Example:
def my_filter(function, iterable):
output = []
for item in iterable:
if function(item):
output.append(item)
return output
the_tuple = (1, 2, 3, 4, 5, 6, 7, 8, 9)
result1 = my_filter(lambda x: x % 2 == 0, the_tuple)
result2 = filter(lambda x: x % 2 == 0, the_tuple)
print(result1)
print(result2)
The output:
[2, 4, 6, 8] # my_filter() outputs a list
(2, 4, 6, 8) # filter() maintains the container type
Advantage 2
From the documentation:
filter(function, iterable) is equivalent to [item for item in iterable if function(item)] if function is not None and [item for item in iterable if item] if function is None.
With the built-in filter, if you pass it None
for the function in its parameters, it defaults to filtering the iterable’s elements based on their truthiness, if element
.
Adjusting my_filter
to support this feature:
def my_filter(function, iterable):
output = []
for item in iterable:
if function:
if function(item):
output.append(item)
elif item:
output.append(item)
return output
the_list = [True, False, 100, "Reed", None, None, "Reedworth"]
result1 = my_filter(None, the_list)
result2 = filter(None, the_list) # Showing the built-in
print(result1)
print(result2)
The output:
[True, 100, 'Reed', 'Reedworth']
[True, 100, 'Reed', 'Reedworth']