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

Andrew Barnert abarnert at yahoo.com
Fri Jul 3 12:17:24 CEST 2015

On Jul 2, 2015, at 23:28, Pierre Quentel <pierre.quentel at gmail.com> wrote:
> 2015-07-03 5:20 GMT+02:00 Andrew Barnert <abarnert at yahoo.com>:
>>> On Jul 2, 2015, at 03:17, Pierre Quentel <pierre.quentel at gmail.com> wrote:
>>> 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 
>>>> 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.
>>> 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.
>> I don't understand how using a function is easier to code and understand than using a function. Or how passing it to range is any simpler than passing it to accumulate, or to a recipe function built on top of accumulate.
> With the proposed addition to raise, the list of powers of 2 lower than 100 would be :
> list(range(1, 100, lambda x:x*2))
> How do you code the same with accumulate ? I tried, but I'm stuck with "stop when the element is >= 100"

A genexpr, a generator function, or a takewhile call.

I already explained how you could write an "irange" function in two lines out of count, accumulate, and takewhile (along with a variety of other useful things). I also suggested that if this isn't obvious enough, it could be a handy recipe in the docs and/or a useful addition to the third-party more-itertools package. So, given that recipe, you'd write it as:

    list(irange(1, 100, lambda x:x*2))

There's no need to add a new itertools.orbit (with a custom C implementation), much less to change range into something that's sometimes a Sequence and sometimes not, when a two-line recipe (that's also an instructive sample) does it just as well.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20150703/8af71f8b/attachment.html>

More information about the Python-ideas mailing list