Path: csiph.com!eternal-september.org!feeder.eternal-september.org!.POSTED!not-for-mail From: Ethan Carter Newsgroups: comp.lang.python Subject: not understanding the result of functools.reduce Date: Fri, 22 Aug 2025 11:46:34 -0300 Organization: A noiseless patient Spider Lines: 66 Message-ID: <87qzx3o1md.fsf@somewhere.edu> MIME-Version: 1.0 Content-Type: text/plain Injection-Date: Fri, 22 Aug 2025 14:46:35 +0000 (UTC) Injection-Info: dont-email.me; posting-host="10712cdfb39b14d84021e67f701bda8d"; logging-data="1711942"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19ECplc7KoOazl/SuKRJV1KFb5JSkZB1co=" Cancel-Lock: sha1:nV+U2WDpWr8/hTg/Sze3BrZwxyM= sha1:CpFC9+7SpCaq9zA5gqSx4mPWt6w= Xref: csiph.com comp.lang.python:197537 # -*- 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.