Guido has talked before about his dislike of the functional-programming map, filter and reduce, prefering comprehensions. So [f(x) for x in L] instead of map and [x for x in L if <condition>] instead of filter.
He also has expressed a general dislike for reduce as confusing, especially given the need for a lambda, and relegating it to functools for python 3, suggesting it is better to use a loop with an accumulator.
I think there is still a case for reduction, but agree that reduce is ugly and confusing as it stands. I’d like to suggest that just as map and filter are more naturally expressed pythonically using comprehensions, so could reduction, by introducing a reduction comprehension:
So, taking a trivial example, instead of
acc = 0
my_list = [2, 3, 4, 5]
for n in my_list:
acc += n
or the confusing and ugly
acc = functools.reduce(lambda acc, n: acc+n, my_list)
we could have something that looks a lot more pythonic:
acc=(acc+n for acc, n reducing my_list)
with the choice of () over other brackets because we are returning a single item as if from a single call to a generator expression. Obviously the keyword reducing could be something else. The word from would be nice, but is already taken.
I think this especially improves things when there is no natural “null” initial state for an accumulator (i.e. as in 0 for addition or 1 multiplication), in which case you need to start with the first item. Take for example wanting to join a list of dataframes together. We might do one of the below:
dfs = [df1, df2, df3, df4]
# slicing to pick the 0th and remaining items
acc = dfs[0]
for df in dfs[1:]:
acc = acc.merge(df)
# create an iterator and use next
dfs_iter = iter(dfs)
acc = next(dfs_iter)
for df in dfs_iter:
acc = acc.merge(df)
# pop the first item if willing to mutate dfs
acc = dfs.pop(0)
for df in dfs:
acc = acc.merge(df)
# use reduce
acc = functools.reduce(lambda acc, df: acc.merge(df), dfs)
Alternatively, we could have an elegant reduction comprehension
acc = (acc.merge(df) for acc, df reducing dfs)
I don’t think this is a particularly more difficult concept to get your head around as a learner than the other comprehensions.