[Python-ideas] Pass a function as the argument "step" of range()

Pierre Quentel pierre.quentel at gmail.com
Sun Jul 5 09:49:54 CEST 2015


Thank you Andrew. This would be a good argument for those who think that
there's nothing you can do with itertools that can't be done in a more
readable and as efficient way without it.

Good argument, but that could be improved with the obvious (and more
complete, you forgot the case stop < start)

import operator

def irange(value, stop, func):
    comp = operator.ge if stop>value else operator.le
    while True:
        if comp(value, stop):
            break
        yield value
        value = func(value)




2015-07-03 22:33 GMT+02:00 Andrew Barnert <abarnert at yahoo.com>:

> On Jul 3, 2015, at 12:37, Pierre Quentel <pierre.quentel at gmail.com> wrote:
> >
> > - the second form requires mastering the functions in itertools, which
> is not the case of all Python developers - after all, itertools is a
> module, its functions are not built-in. Even those who do hesitate between
> count() and accumulate().
>
> Nobody "hesitates" between count and accumulate. They do completely
> different things. And I think everyone who's answered you, and everyone
> who's read any of the answers, understands that. It's only because you
> described "powers of two" analytically in text, but "multiply the last
> value by two" iteratively in pseudocode, that there's a question of which
> one to use. That won't happen in any real-life cases.
>
> Of course people who haven't "mastered" itertools and aren't used to
> thinking in higher-level terms might not think of accumulate and takewhile
> here; they might instead write something like this:
>
>     def iterate(func, start):
>         while True:
>             yield start
>             start = func(start)
>
>     def irange(start, stop, stepfunc):
>         for value in iterate(stepfunc, start):
>             if value >= stop: break
>             yield value
>
>     for powerof2 in irange(1, 1000, lambda n:n*2):
>         print(powerof2)
>
> But so what? It's a couple lines longer and maybe a tiny bit slower (at
> least in CPython; I wouldn't be too surprised if it's actually faster in
> PyPy...), but it's perfectly readable, and almost certainly efficient
> enough. And it's abstracted into a pair of simple, reusable functions,
> which you can always micro-optimize later if that turns out to be necessary.
>
> People on places like Reddit or StackOverflow like to debate about what's
> the absolute best implementation for any idea, but if the naive
> implementation that a novice would come up with on his own is good enough,
> those debates aren't relevant except as a fun little challenge, or a way to
> explore different parts of the language; the good enough code is good
> enough as-is. So, this just falls into the "not every 3-line function needs
> to be in the stdlib" category.
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20150705/d1f9e250/attachment-0001.html>


More information about the Python-ideas mailing list