Appearance
filter
The built-in filter()
function in Python is used to filter sequences.
Similar to map()
, the filter()
function also takes a function and a sequence as arguments. However, unlike map()
, filter()
applies the given function to each element in the sequence, and keeps or discards the element based on whether the function returns True
or False
.
For example, to remove even numbers from a list and keep only odd numbers, you can write:
python
def is_odd(n):
return n % 2 == 1
list(filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15]))
# Result: [1, 5, 9, 15]
To remove empty strings from a sequence, you can write:
python
def not_empty(s):
return s and s.strip()
list(filter(not_empty, ['A', '', 'B', None, 'C', ' ']))
# Result: ['A', 'B', 'C']
As seen, the key to using filter()
, a higher-order function, is correctly implementing a "filtering" function.
Note that the filter()
function returns an Iterator
, which is a lazy sequence. Therefore, to force filter()
to compute the result, you need to use the list()
function to obtain all results and return a list.
Using filter to Find Prime Numbers
One method for calculating prime numbers is the Sieve of Eratosthenes, which is quite simple to understand:
Start by listing all natural numbers from 2 onwards, constructing a sequence:
2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...
Take the first number in the sequence, 2, which is a prime number, and use it to filter out all multiples of 2:
3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...
Take the next number, 3, which is also a prime number, and use it to filter out all multiples of 3:
5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...
Continue this process by taking the first number, 5, and using it to filter out all multiples of 5:
7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...
By continuing this filtering process, all prime numbers can be obtained.
To implement this algorithm in Python, you can first construct an odd number sequence starting from 3:
python
def _odd_iter():
n = 1
while True:
n = n + 2
yield n
Note that this is a generator and an infinite sequence.
Next, define a filtering function:
python
def _not_divisible(n):
return lambda x: x % n > 0
Finally, define a generator that continually returns the next prime number:
python
def primes():
yield 2
it = _odd_iter() # Initial sequence
while True:
n = next(it) # Return the first number in the sequence
yield n
it = filter(_not_divisible(n), it) # Construct a new sequence
This generator first returns the prime number 2, then uses filter()
to continually produce a new filtered sequence.
Since primes()
is also an infinite sequence, a condition must be set to exit the loop when calling it:
python
# Print prime numbers below 1000:
for n in primes():
if n < 100:
print(n)
else:
break
Note that an Iterator
is a lazily computed sequence, allowing Python to express sequences such as "all natural numbers" or "all prime numbers" very concisely.
Exercise
A palindrome is a number that reads the same from left to right as it does from right to left, such as 12321 or 909. Use filter()
to filter out palindromes:
python
def is_palindrome(n):
pass
# Test:
output = filter(is_palindrome, range(1, 1000))
print('1~1000:', list(output))
if list(filter(is_palindrome, range(1, 200))) == [1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 22, 33, 44, 55, 66, 77, 88, 99, 101, 111, 121, 131, 141, 151, 161, 171, 181, 191]:
print('Test passed!')
else:
print('Test failed!')
Summary
The purpose of filter()
is to filter out elements from a sequence that meet specific conditions. Because filter()
uses lazy evaluation, the filtering occurs only when retrieving the results, returning each filtered element one at a time.