You mean these critics find
>>> map(lambda x: x**2, filter(lambda x: not x % 2, range(11)))
preferable to the "fragmented": def square(x):
return x ** 2
def is_even(x):
return not x % 2
>>> (square(x) for x in range(11) if is_even(x))
Both result in the same lazy iteration (to see results below - requires materialization with a constructor like list or tuple), but I find the "fragmented" approach much more readable (so long as the functions do what their name says they do - I have seen Python where they actually did the opposite...) >>> list((square(x) for x in range(11) if is_even(x)))
[0, 4, 16, 36, 64, 100]
>>> list(map(lambda x: x**2, filter(lambda x: not x % 2, range(11))))
[0, 4, 16, 36, 64, 100] # square even numbers
range(11)
.filter(lambda x: not x % 2)
.map(lambda x: x ** 2)
However such a chaining API is not practical in python, because lambda syntax is voluntarily crippled to one expression only.For example I often end up doing:
something(
"Template string {thing}"
.format(thing=33)
) label = "Template string {thing}".format(thing=33)
something(label)Storing each step in variables has the advantage to be self-documenting and nicer when debugging. However in many cases I feel like wasting energy trying to find short and adequate variable names for each steps in a computation, especially when the steps are clear enough by themselves but difficult to describe in 1-2 short words.
You also need to keep the variable names in sync when refactoring, which may cause even more refactoring if the line gets too long with the new name.
IMO it makes sense to use both styles where they feel most adequate.
In the real world you filter water to get the water. In most programming languages filter() is more like a strainer or colander.
My guess is you ran into someone stubbornly insisting on the meaning of the word filter despite all evidence.