reduce in Python. In doing so, we have defined two closely related functions, fold1 and scan. Since they're so similar, it makes sense to briefly digress and consider bundling them together into a class. I won't make much use of the class in future installments of this series, but it is an interesting exercise to consider alternative definitions that might be a better fit to Python. Define:
class Fold(object):The
def __init__(self, function, init):
self.function = function
self.init = init
def __call__(self, acc, x):
return self.function(acc, x)
def scan(self, iterable):
function = self.function
acc = self.init
yield acc
for x in iterable:
acc = function(acc, x)
yield acc
def fold(self, iterable):
for x in self.scan(iterable): pass
return x
Fold class is defined to take the function and initial value for the accumulator when the class is instantiated. This gives us some of the benefits we saw for the curried SML functions. Putting the
Fold class to use, we can define the sum and cumsum functions that we saw last time:sum = Fold(operator.add, 0).foldPerhaps more useful is to define something like<
cumsum = Fold(operator.add, 0).scan
add = Fold(operator.add, 0)and then using
add.scan and add.fold as needed. Indeed, any function of two arguments could be given this treatment, so long as a sensible default (or identity) value can be given. Note that the
min3 function from last time is not well suited to this sort of treatment, because it has no clear default value. However, the Fold class presents no additional difficulties over separate fold and scan functions. 1 As a reminder,
fold is another name for reduce. We'll continue to reserve reduce as the name of the Python built-in function.
No comments:
Post a Comment