Reputation: 1388
I'm trying to write a code that uses only lambdas, filter, map and reduce (its a riddle) that accepts a tuple of integers and a tuple of functions, and returns a new tuple of integers who only return one true from the list of functions:
As an example, if the tuple is (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
and the tuple of functions is (lambda x: x > 3, lambda x: x % 2 == 0)
I should get a new tuple that looks like [2, 5, 7, 9]
because they make only one of the two rules to return True. this is my code so far and I have no idea how to do that...
func = (lambda x: x > 3, lambda x: x % 2 == 0)
data = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
a = lambda func, data: tuple(filter(lambda x: tuple(filter(None, map(lambda f: f(x), func))), data))
print(a(func, data))
This code returns only the integers that apply to both of the terms, but I need to make it to just one.
Upvotes: 0
Views: 97
Reputation: 15249
Here it is:
a = lambda func, data: tuple(filter(lambda d: (sum(map(lambda f: f(d), func)) == 1), data))
Since this really is just a contrived exercise for the sake of it I won't endeavor explaining this horrible expression. But the way to get to it is to first write the code in a clear way with for
loops, if
blocks etc..., and then one step at a time replace each component with the appropriate map
, filter
etc...
The one trick I use here is automatic boolean conversion to int: sum(sequence_of_bool) == 1
means exactly one bool is True
.
My full test code:
func = (lambda x: x > 3, lambda x: x % 2 == 0)
data = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
a = lambda func, data: tuple(filter(lambda d: (sum(map(lambda f: f(d), func)) == 1), data))
print(a(func, data))
(2, 5, 7, 9)
Upvotes: 1
Reputation: 107134
You can use bool.__xor__
to ensure that only one of the two functions in the func
tuple is satisfied:
from functools import reduce
tuple(filter(lambda x: reduce(bool.__xor__, map(lambda f: f(x), func)), data))
This returns:
(2, 5, 7, 9)
Upvotes: 0