The function map maps; while the filter Filter. They're not equivalent and never one will replace the other. It is actually quite common to use them together (the map and filter operations, not necessarily the functions).The function map ensures that there will always be a result for each input value. Strictly speaking we can affirm that the length of the sequence result of a mapping will always be equal to that of the mapped sequence.See that in your example you mapped the sequence [2, 3, 4, 5] and begot [1, 2, 3, 4]. Each element of the input generated a value in the output.Even if you apply a function that does not explicitly have a return during mapping a value will be generated at the output None respective:def pares(x):
if x % 2 == 0:
return x
print(list(map(pares, range(10))))
[0, None, 2, None, 4, None, 6, None, 8, None]
The function filter aims to reduce the input sequence based on the conditions defined by the filter. It is not guaranteed that always the generated sequence is smaller than the original sequence because there is the case of all the elements satisfy the condition of the filter, but it is certain that never the sequence will be greater than the original sequence. There is also a certainty that all the generated sequence values also belong to the original sequence. That is, if filter(A) production B, then the intersection of A with B will always be B.This can be observed when you apply a filter in sequence [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] with the aim of searching only the pair numbers, obtaining [2, 4, 6, 8, 10].In fact, so much map how filter are classes and therefore are not basically called functions, but rather instanciations of the respective classes. Both instances are iterable objects that will produce the values of the final sequence when consumed by demand. That is, the result sequence is not stored in memory, but rather produced element to element when it is iterated (so the return is converted to a list before displaying).About using them together, imagine a sequence of users with the fields email and ativo.users = [
('felix@servidor', True),
('caitie@servidor', True),
('joel@servidor', False),
('violet@servidor', False),
('traci@servidor', True)
]
The goal is to get the email list of active users only.With map we can extract the email information and return a list with this information:def get_email(user):
return user[0]
print(list(map(get_email, users)))
['felix@servidor', 'caitie@servidor', 'joel@servidor', 'violet@servidor', 'traci@servidor']
But we don't want all the emails. So we use the filter to get only those assets:def is_active(user):
return user[1] == True
print(list(filter(is_active, users)))
[('felix@servidor', True), ('caitie@servidor', True), ('traci@servidor', True)]
But we don't want all the information, just the email. So we put together the two:emails = map(get_email, filter(is_active, users))
print(list(emails))
['felix@servidor', 'caitie@servidor', 'traci@servidor']
But this is hardly used in practice because it is not an easy-to-read code while using the list comprehension gets much easier and produces the same result:emails = [get_email(user) for user in users if is_active(user)]
print(emails)
['felix@servidor', 'caitie@servidor', 'traci@servidor']
Part get_email(user) makes mapping paper while if is_ative(user) Make the filter.If it were to translate the behavior of both in a purely Python function, we would have the function map:def map(function, *iterables):
for values in zip(iterables):
yield function(*values)
While the function filter would be:def filter(function, iterable):
for value in iterable:
if function(value):
yield value
In summary:map you control which will be the returned value, but not when will be returned (always returns something);filter you control when will be returned, but not which will be the returned value (always return the original value);