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

Pierre Quentel pierre.quentel at gmail.com
Thu Jul 2 12:17:57 CEST 2015

```2015-07-02 9:32 GMT+02:00 Andrew Barnert via Python-ideas <
python-ideas at python.org>:

> LOn Jul 2, 2015, at 00:12, Nathaniel Smith <njs at pobox.com> wrote:
>
> On Jul 1, 2015 23:56, "Ben Finney" <ben+python at benfinney.id.au> wrote:
> >
> > Pierre Quentel <pierre.quentel at gmail.com>
> > writes:
> >
> > > To achieve the same thing in Python we currently can't use range()
> > > because it increments by an integer (the argument "step"). An option
> > > is to build a generator like :
> > >
> > > def gen(N):
> > >     i = 1
> > >     while i<=N:
> > >         yield i
> > >         i *= 2
> > >
> > > then we can iterate on gen(N).
> >
> > Generators can be defined in expressions, of course::
> >
> >     ((x * 2) for x in range(n))
> >
> > So the full function definition above is misleading for this example.
> >
> > Your single example defines the ‘step’ function in-line as a lambda
> > expression::
> >
> > > Iterating on the powers of 2 below N would be done by :
> > >
> > > for i in Range(1, N, lambda x:x*2)
> >
> > So why not define the generator as an expression::
> >
> >     for i in ((x * 2) for x in range(n)):
> >
> > That seems quite clear given existing syntax.
>
> I believe the original example was actually
>
> for i in ((2 ** (x + 1) for x in range(int(log2(n)))):
>
> or similar... which is clearly making some sort of argument about clarity
> but I'm not sure what.
>
> This isn't going to work for range() anyway though AFAICT because range
> isn't an iterator, it's an iterable that offers O(1) membership tests.
>
> I could see an argument for putting something along these lines in
> itertools. itertools.orbit, maybe. But I've never felt an urgent need for
> such a thing myself.
>
> You can already do this with accumulate; you just have to write lambda x,
> _: x*2.
>
> Of course it doesn't include the built-in bounds, but I don't think you'd
> want that anyway. With accumulate, you can bound on the domain by passing
> range instead of count for the input, bound on the range with takewhile, or
> generate an infinite iterator, or anything else you think might be useful.
>
> Or one more of the various combinations of things you can trivially build
> out of these pieces might be useful as a recipe ("irange"?) and/or in the
> third-party more-iterools.
>
> _______________________________________________
> 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/
>

I am not saying that you can't find other ways to get the same result, just
that using a function (usually a lambda) is easier to code and to
understand.

The proposal would bring to Python one of the few options where iteration
is more simple in Java or Javascript than with Python - I had the idea from
this discussion on reddit :