2008/4/26 Alexander Belopolsky <[EMAIL PROTECTED]>:

> > What is range()?
>  >
>  > help(range) shows me that range "Returns an iterator that generates
>  > the numbers in the range on demand."
>
>  This is not correct in 3.x: range does not return an iterator.  There is an
>  iterator similar to range in itertools: count.   I would not mind adding
>  optional step and stop arguments to it.

I took that string doing help(range) in the py3k branch, r62509, is it a bug?

Which should the range() definition be, in your words?


>  > Ahá! So, as ints are unbound in Python, I could easily do:
>  >
>  > >>> r = range(1,1000000000000000000000)
>
>  The problem with supporting this is that len(r) will raise overflow error.
>  It would be nice to get rid of the limitation on len(), but it will be hard
>  and may not be possible to do efficiently.

Maybe len() should be removed? Maybe indexing? I don't know: I don't
know what range() is. I mean, I took the previous definition from the
actualy Py3k, but you say it's wrong.

I think that we should first define the range() semantic, what is core
to it and what would be a nice thing to have but is not mandatory, and
then try to comply.

At this moment I stopped writing this mail, and I went to code a
Range() class to have the semantics that we're seeking here (it's
attached), and I couldn't finish it 100% because of a len() behaviour
that I'm including here, because it's related to what we're discussing
here:

>>> class C:
...     def __len__(self):
...             return 100000000000000000000000000000
...
>>> c = C()
>>> len(c)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
    OverflowError: Python int too large to convert to C ssize_t

>From an external point of view, and knowing that ints are unbound, why
should I have an error here?

Thanks!

-- 
. Facundo

Blog: http://www.taniquetil.com.ar/plog/
PyAr: http://www.python.org/ar/
class Range:
    def __init__(self, frm=None, to=None, step=None):
        if to is None:
            self.frm = 0
            self.to = frm
        else:
            self.frm = frm
            self.to = to
        if step is None:
            self.step = 1
        else:
            self.step = step

        print(self.frm, self.to, self.step)
        self.point = self.frm

    def __iter__(self):
        return self.__next__()

    def __next__(self):
        while True:
            if self.step > 0 and self.point >= self.to:
                break
            if self.step < 0 and self.point <= self.to:
                break
            yield self.point
            self.point += self.step
        
    def __len__(self):
        lim = self.to - self.frm
        d, r = divmod(lim, self.step)
        if r:
            d += 1
        return d

    def __getitem__(self, pos):
        return self.frm + self.step * pos

if __name__ == "__main__":
    r = Range(6)
    assert list(r) == [0, 1, 2, 3, 4, 5]
    assert len(r) == 6
    assert r[2] == 2

    r = Range(2, 9)
    assert list(r) == [2, 3, 4, 5, 6, 7, 8]
    assert len(r) == 7
    assert r[2] == 4

    r = Range(2, 9, 2)
    assert list(r) == [2, 4, 6, 8]
    assert len(r) == 4
    assert r[2] == 6

    r = Range(13, 4, -2)
    assert list(r) == [13, 11, 9, 7, 5]
    assert len(r) == 5
    assert r[2] == 9

    r = Range(1000000000000000000000)
    assert r[2] == 2
    assert len(r) == 1000000000000000000000

_______________________________________________
Python-3000 mailing list
Python-3000@python.org
http://mail.python.org/mailman/listinfo/python-3000
Unsubscribe: 
http://mail.python.org/mailman/options/python-3000/archive%40mail-archive.com

Reply via email to