why won't slicing lists raise IndexError?

Paul Moore p.f.moore at gmail.com
Mon Dec 4 16:30:10 EST 2017


On 4 December 2017 at 20:13, Jason Maldonis <jjmaldonis at gmail.com> wrote:
> And I'll be honest -- I like the implementation of the LazyList I wrote
> above. I think it's pretty logical, because it allows you to think about
> the lazy list like this:  "Treat the list like a norma list. If you run out
> of bounds, get more data, then treat the list like a normal list again."
> And I really like that clean logic.

I can't give you a definitive answer as to why slices behave as they
do, any more than anyone else (barring probably Guido). But as a user,
I can say that I find the ability to use slices without checking for
out of bounds cases or handling exceptions to be really convenient.
And one thing Python consistently emphasises is making things easy for
the user, even if that convenience comes at a cost to the implementer.
Certainly, you're a user of the built in list class, but you're using
it to build a wrapper around it, and that makes you a non-core use
case (as I see it). At the end of the day, whether to clamp the values
or raise IndexError is a trade-off in terms of which type of user to
inconvenience, and as I say, in my experience user code wins when that
sort of trade-off comes up.

That's not to say Python makes it deliberately difficult for people
writing code like yours. For your lazy list class, do you know the
maximum amount of data available? If you don't, then supporting
lst[:-1] will be hard, so you're pretty much bound to have to handle
slices differently than built in lists. If you *do* know the maximum
length of the underlying data, then the indices() method of slices
will probably help:

Help on built-in function indices:

indices(...) method of builtins.slice instance
    S.indices(len) -> (start, stop, stride)

    Assuming a sequence of length len, calculate the start and stop
    indices, and the stride length of the extended slice described by
    S. Out of bounds indices are clipped in a manner consistent with the
    handling of normal slices.

Using indices(), you'll get (from "stop") the amount of data you need to load.

Paul



More information about the Python-list mailing list