# -*- mode: python; python-indent-offset: 2 -*-
from functools import reduce
## I'm puzzle with this result of reduce. Can you spot where my mind
## is going wrong?
##
## The problem I want to solve with /reduce/ (merely for the sake of
## exercise) is to collapse a list of lists to a list of booleans.
## The lists given as input can contain strings or integers. The
## output value for each list will be True if the input list contains
## an integer; False otherwise. For example, the desired
## transformation is
##
## [["a","b"], ["a", 1]] --> [False, True]
##
## because only the second list has an integer. The exercise is to
## use only map, filter and reduce. The problem can be solved by
## mapping a function that reduces each list to the desired boolean.
## Here's the scheme of a solution:
def solution(ls):
return list(map(transform, ls))
## To transform each list, we can apply reduce with a suitable binary
## operator here called /op/
def transform(ls):
return reduce(op, ls, False)
## The question is how to write such an operator. I wrote this one:
def op(x, b):
return isinstance(x, int) or b
## My hand computation produces the correct answer, but when I invoke
## functools.reduce, I get [True, True, ...] no matter what. For
## example:
## >>> solution([[""],["aa",1]])
## [True, True]
## which is not correct. When I write my own reduce function, I get
## the expected results. Here's two implementations of my
## understanding of reduce:
def reduc1(op, ls, init):
if ls == []:
return init
return op(ls[0], reduc1(op, ls[1:], init))
def reduc2(op, ls, init):
r = init
for x in ls:
r = op(x, r)
return r
## They both compute the expected result:
##
## >>> list(map(lambda ls: reduc1(op, ls, False), [[""], ["aa",1]]))
## [False, True]
##
## >>> list(map(lambda ls: reduc2(op, ls, False), [[""], ["aa",1]]))
## [False, True]
##
## Can you help? Thanks so much.
--
https://mail.python.org/mailman3//lists/python-list.python.org