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

Nick Coghlan ncoghlan at gmail.com
Sat Jul 4 02:17:10 CEST 2015

```On 4 Jul 2015 7:25 am, "Terry Reedy" <tjreedy at udel.edu> wrote:
>
> On 7/3/2015 7:23 AM, Nick Coghlan wrote:
>>
>> On 3 July 2015 at 06:20, Pierre Quentel <pierre.quentel at gmail.com> wrote:
>>>
>>> @Steven, Mark
>>> The definition of range() in Python docs says :
>>>
>>> Python 2.7 : "This is a versatile function to create lists containing
>>> arithmetic progressions. It is most often used in for loops."
>>>
>>> Python 3.4 : "The range type represents an immutable sequence of
numbers and
>>> is commonly used for looping a specific number of times in for loops."
>>
>>
>> Pierre, I *wrote* the Python 3 range docs.
>
>
> I think deleting 'arithmetic' was a mistake.  Would you mind changing
'immutable sequence' to 'immutable arithmetic sequence'?

Sure, clarifications aren't a problem - getting "arithmetic progression"
back in the docs somewhere will be useful to folks familiar with the
mathematical terminology for how range works.

> Also, I think 'numbers' should be narrowed to 'integers' (or whatever is
actually accepted).  The idea of allowing floats has been proposed at least
once, probably more, and rejected.

Unfortunately, we don't have a great word for "implements __index__", as
"integer" at least arguably implies specifically "int".

>> There isn't a "general idea" behind Python 3's range type, there's a
>> precise, formal definition.
>
>
> 'predictable finite increasing or decreasing arithmetic sequence of
integers, efficiently implemented'

Ah, I like that.

> range() looks at the value of step to decide whether to raise or return.
Something must look as the sign of step to decide whether stop is a max or
min, and what comparison to use.  Since the sign is constant, this
determination need only be done once, though I do not know where or when it
is currently done.
>
> Given that a function has neither a value nor sign, and each call can
have not only a different value, but a different sign.  A step function is
a very messy fit to an api with a stop parameter whose meaning depends on
the sign of step. For many sequences, one would want an explicit max or min
or both.

Yeah, I started trying to think of how to do this generically, and I think
it would need to be considered in terms of upper and lower bounds, rather
than a single stop value.

That is, there'd be 6 characterising values for a general purpose computed
sequence:

* domain start
* domain stop
* domain step
* range lower bound
* range upper bound
* item calculation

However, you fundamentally can't make len(obj) an O(1) operation in that
model, since you don't know the output range without calling the function.

So the general purpose form could be an iterator like:

def within_bounds(iterable, lower, upper):
for x in iterable:
if not lower <= x < upper:
break
yield x

Positive & negative infinity would likely suffice as defaults for the lower
& upper bounds.

Cheers,
Nick.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20150704/86b11a28/attachment.html>
```