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

Andrew Barnert abarnert at yahoo.com
Thu Jul 2 09:32:35 CEST 2015


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.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20150702/de621660/attachment.html>


More information about the Python-ideas mailing list