Sunday, November 24, 2013

This week we have covered 3 different topics: equality, hiding attributes and reduce. The topic this week which particularly interests me was the build in reduce function. In a typical computer science exercise, we may be asked to find the maximum element within a nested list. With the build in function max(), this is a very easy exercise. However, many times in practice, we may not have tasks as nice as this. For instance, we maybe asked to pick, out of a nested list of string, the string that contains the most vowels. Although still simple, it is a more complicated task comparing to the maximum problem. And in this case, we may utilize the reduce function in other to carry out the task. The code for this task is posted is the following:

def most_vowels1(x,y):
    return max([[sum([x.count(i) for i in 'aeiou']),x], [sum([y.count(i) for i in 'aeiou']),y]])[1]
def most_vowels(L:"iterable"):
    return None if L == [] else reduce(most_vowels1, [most_vowels(i) if isinstance(i, list) else i for i in L])

In my personal perspective, I think using the reduce function in conjunction with recursion can truly yield elegant solutions to a wide range of problems. In the above code, recursion within a list comprehension was used in other to deal with nested lists. The most_vowels1 is a helper function which helps to find the string with the highest occurrence of vowels out of  only two inputs. The most vowels function implements the reduce function and greatly simplifies the code due to the built in algorithm. This approach can usually simplify a problem due to the fact that what is needed to be performed and compared among ALL elements of a nested list can be broken down to what is needed to be performed to only 2 elements. This make the coding much easier and the recursive nature of the final input much easier to handle.
Another thing to note is that the approach above in solving the vowel problem is rather generic. Compare the above code with the following code which sums all elements within a list:

def my_add(x,y):
    return x+y
def my_sum1(L:"iterable"):
    return 0 if L == [] else reduce(my_add,[my_sum1(i) if isinstance(i,list)  else i for i in L])

Notice the rather remarkable similarity to the first block of code. Especially in the second function, the syntax is almost exactly the same. This emphasizes the generality of the reduce function and the fact that it may be used for any arbitrary function which defined with respect to two inputs of the same type and returns data with the same type. Therefore , in other to use the reduce function to the fullest extend, this is something good to keep in mind.

No comments:

Post a Comment