Strange range

Steven D'Aprano steve at pearwood.info
Fri Apr 1 09:26:09 EDT 2016


On Sat, 2 Apr 2016 12:15 am, Marko Rauhamaa wrote:

> 
> This seems sane:
[...] 
> This not so much:
> 
>     >>> it = range(10)
>     >>> for i in it:
>     ...   if i >= 3:
>     ...      break
>     ...
>     >>> list(it)
>     [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
> 
> Note to self: range(10) is an iterator factory, not an iterator.

Incorrect. range is a lazy sequence.

The only difference between [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] and range(10) is
that the list [0, ..., 9] is calculated eagerly, ahead of time, while
range(10) only generates the values on demand. You can think of range as
equivalent to something close to this:


class Range(object):
    def __init__(self, start, end, step=1):
        self.start = start
        self.end = end
        self.step = step

    def __getitem__(self, index):
        value = self.start + (index-1)*self.step
        if value < self.end:
            return value
        raise IndexError

    def __iter__(self):
        try:
            index = 0
            while True:
                yield self[index]
                index += 1
        except IndexError:
            return



except with more error checking, better bounds checking, support for the
`in` operator, etc.



-- 
Steven




More information about the Python-list mailing list