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

Pierre Quentel pierre.quentel at gmail.com
Fri Jul 3 12:23:48 CEST 2015

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

> 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.
>

Well, you still haven't given an example with accumulate, have you ? I
expected that. There is a good answer in the reddit thread :

from itertools import count, takewhile
list(takewhile(lambda n: n <= 100, (2**n for n in count())))

My point here is that even with this simple example, it's not clear even
for people who know itertools well to remember which function to use.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20150703/c8ddc89d/attachment-0001.html>