Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #197538

Re: not understanding the result of functools.reduce

From ram@zedat.fu-berlin.de (Stefan Ram)
Newsgroups comp.lang.python
Subject Re: not understanding the result of functools.reduce
Date 2025-08-22 15:30 +0000
Organization Stefan Ram
Message-ID <order-20250822162642@ram.dialup.fu-berlin.de> (permalink)
References <87qzx3o1md.fsf@somewhere.edu>

Show all headers | View raw


Ethan Carter <ec1828@somewhere.edu> wrote or quoted:
>## The question is how to write such an operator.  I wrote this one:
>def op(x, b):
>  return isinstance(x, int) or b

  The main snag with your op function and how you're using
  reduce is the switch-up in the argument order that "reduce"
  expects versus how you set up op.

  "functools.reduce" calls the reducer function "op" with two
  arguments: the accumulated value so far first, then the
  next element from the iterable.

  You wrote "op" as "op(x, b)", where you treat "x" like an element
  and "b" like a boolean accumulator, but actually "reduce" hands
  the accumulator first, then the element.

  So when "reduce" runs, the first argument "x" is actually the boolean
  accumulator, and the second "b" is the next element.

  The fix:

  You want to flip your operator function so the accumulator is
  the first argument, and the element is second:

def op(x, b):
    return x or isinstance(b, int)

  That way, the accumulator keeps track if any integer's popped up
  so far, and you update it by or'ing that with whether the current
  element is an int. 

  Why your custom reduce versions worked:

  Your custom reduce functions call "op" like "op(ls,
  reduc1(...))" or "op(x, r)" in the loop, so your argument order
  is reversed from functools.reduce, which is why you didn't
  see this problem there. Correct version example:

from functools import reduce

def op(acc, elem):
    return acc or isinstance(elem, int)

def transform(ls):
    return reduce(op, ls, False)

def solution(ls):
    return list(map(transform, ls))

print(solution([[""], ["aa", 1]]))   Output: [False, True]
print(solution([["a", "b"], ["a", 1]]))   Output: [False, True]

  This will give the right output now, checking if each sublist
  has any integer and returning "True" or "False" accordingly.

Back to comp.lang.python | Previous | NextPrevious in thread | Next in thread | Find similar


Thread

not understanding the result of functools.reduce Ethan Carter <ec1828@somewhere.edu> - 2025-08-22 11:46 -0300
  Re: not understanding the result of functools.reduce ram@zedat.fu-berlin.de (Stefan Ram) - 2025-08-22 15:30 +0000
    Re: not understanding the result of functools.reduce Ethan Carter <ec1828@somewhere.edu> - 2025-08-22 12:45 -0300

csiph-web