[Python-ideas] Add nullifier argument to functools.reduce?

David Mertz mertz at gnosis.cx
Sat Aug 23 20:43:42 CEST 2014


It's true, Steven, that we'd have to use itertools.accumulate() rather than
functools.reduce() to do the heavy lifting here (as Bob suggested).  But
using that, here are three lines:

  from itertools import *
  from operator import add

  def reduce_with_attractor(func, it, start=ℵ, end_if=ℵ):
      it = iter(it)
      start = start if start≢ℵ else it.__next__()
      return list(takewhile(λ x: x≢end_if,
                            accumulate(chain([start],it), func)))[-1]

Oh, that's cute... my copy-paste was using
https://github.com/ehamberg/vim-cute-python (somewhat customized further by
me).  In regular ASCII:

  def reduce_with_attractor(func, it, start=None, end_if=None):
      it = iter(it)
      start = start if start!=None else it.__next__()
      return list(takewhile(lambda x: x!=end_if,
                            accumulate(chain([start],it), func)))[-1]

This gives you the accumulation up-to-but-not-including the attractor.  I
guess the OP wanted to return the attractor itself (although that seems
slightly less useful to me).  I'd have to play around to get that version
in three lines... maybe it would take 4 or 5 lines to do it.


On Sat, Aug 23, 2014 at 10:43 AM, Steven D'Aprano <steve at pearwood.info>
wrote:

> On Sat, Aug 23, 2014 at 10:25:06AM -0700, David Mertz wrote:
> > This "nullifier" is mathematically called an "absorbing element", but
> > saying an "attractor" might be a little more general.  I.e. think of a
> > local optimization problem, where multiple local min/max points might
> > occur.  If you reach one, further iteration won't budge from that point,
> > even if it's not the "global absorbing element."
>
> Yes. Note that arbitrary systems may have more than one attractors,
> including cycles (a -> b -> c -> a) and even "strange attractors" of
> infinite complexity. It's probably too much to expect reduce to deal
> with cycles, but a really general solution should at least deal with
> multiple attractors.
>
> > Given that one can easily write one's own three line wrapper
> > 'reduce_with_attractor()' for this special semantics
>
> I don't think you can. Although it's 3:30am here and it's past my bed
> time, so perhaps I'm wrong. The problem is that the wrapper cannot see
> the reduced value until reduce() returns, and we want to short-circuit
> the call once the reduced value is the attractor.
>
> Still, easy or not, I think the semantics are too specialised to
> justify in the standard library, especially given that Guido doesn't
> like reduce and it almost got removed. A better solution, I think, would
> be to stick this reduce_with_attractor() in some third-party functional
> tool library.
>
>
> --
> Steven
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>



-- 
Keeping medicines from the bloodstreams of the sick; food
from the bellies of the hungry; books from the hands of the
uneducated; technology from the underdeveloped; and putting
advocates of freedom in prisons.  Intellectual property is
to the 21st century what the slave trade was to the 16th.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20140823/6b3fdb47/attachment-0001.html>


More information about the Python-ideas mailing list