1
votes

Let us consider a list with numbers like the following :

a_lst = [1,2,3,2,3,4,5,6,2,2]

Now I need to write a program in python which counts the number of occurrences of let's say "2" using only "reduce" .

I went through the following question as well :

using Python reduce Count the number of occurrence of character in string

It has got a great answer , however I wanted to see if there is any way where I could replace the "if" condition inside the lambda function with like (x == 2) . I mean getting the same thing done by not using the "if"condition explicitly .

I thought of reaching up to a solution by passing a lambda function,which takes another lambda function as an argument to the reduce function . But it turned out to be just a day-dream and nothing else as after passing a lambda function as an argument , calling it inside the outer lambda function body will defeat the purpose of making it a lambda function .

One more fiasco was about wishing for a construct where a lambda function could call itself at the end of its body . (I understand the above line sounds completely meaningless , but what I meant a construct which had the equivalent power of a lambda calling itself )

I have been through the concept of continuation passing style ,where in pythonic terms , a function returns a lambda function which takes the arguments that the function had received .But I am not sure if by definition of continuation is technically accurate . Can it be brought to use to solve this problem ?

1
Are you taking about fixed points? If fix = lambda f: lambda n: f(n, f), then fact = fix(lambda n, f: 1 if n == 0 else n*f(n-1, f)) defines a factorial function without explicit recursion. - chepner
@chepner : This was interesting . But one small query . when "fix" is defined like this , it should be taking 2 arguments right ? But here in the second line fix took one argument which is the lambda function . Could you help me in this part ? - Erwin Kairos
Kind of. This might not be precisely correct, but it captures the feel: just like the fixed point of a single-argument function is a value, the fixed point of a two-argument function is a single-argument function. fact(n) = n!, then, is the fixed-point of a two-argument function foo(n, f) = 1 if n == 0 else n * f(n-1, f). - chepner
Put another way, fix takes a two-argument function and returns a single-argument function. The return value of fix in this example is the single-argument function fact. (It's probably a little clearer written out with def statements, but lambda expressions fit in comments better.) - chepner

1 Answers

2
votes

Theres nothing stopping you from writing

the lambda function with like (x == 2)

from functools import reduce
a_lst = [1,2,3,2,3,4,5,6,2,2]
reduce(lambda x, y: x + (y == 2), a_lst, 0) #Output: 4

The reason this works is because bool is a subclass of int in python, and can be used for mathematical operations.

If that alone however does not satisfy you, you can get really involved with the operator and functools modules. Reference docs.

from functools import reduce, partial
import operator
reduce(operator.add,map(lambda x: operator.eq(x, 2), a_lst), 0) #Output: 4

and, replace the lambda with a partial function

equals_2 = partial(operator.eq, 2)
reduce(operator.add,map(equals_2, a_lst), 0) #Output: 4

A Word of caution
It may not be wise to get stuck with one paradigm of programming (functional) in this case. Python excels in allowing any programming paradigm, but practically beats purity. It is just much simpler and easier to iterate through the list and count the number of 2s yourself, using the .count method. No need to reinvent the wheel where it doesn't make sense. To future readers, this is just a demonstration, not a recommendation on how to count occurrences in a list.