why won't slicing lists raise IndexError?

Jason Maldonis jjmaldonis at gmail.com
Mon Dec 4 15:13:30 EST 2017


>Why would this simplify your code? What are you doing that would benefit
>from an IndexError here?

Without simplifying too much, I'm writing a wrapper around a REST API. I
want lazy-loading functionality for lists-of-things, so I am creating a
LazyList class.

This LazyList class will load items as needed, and store them on the list.
When a user triggers `__getitem__`, the LazyList may not yet have data for
the index the user requests, in which case it needs to load more data. I'll
write out the basic functionality of the LazyList class so you can
explicitly see how slicing is impacting the implementation:

class LazyList(list):
    def __getitem__(item):
        try:
            return super().__getitem__(item)
        except IndexError:
            self._generate_more_data(item)  # If, for example, item == 10,
this function will keep generating more data until there are 10 items in
the list
            return super().__getitem__(item)


This works great when `item` is an integer.  However, when `item` is a
slice, the IndexError is never triggered, and so new data will never be
loaded. Consider this snippet:

lazy_list = LazyList()
sublist = lazy_list[:10]

In this case, `sublist` will always be empty, because the first `return
super().__getitem__(item)` "succeeds" by returning an empty list. If
slicing raised an IndexError, the above code would work great.  Instead, I
need to add a check before the try/except to check if the `item` is a
`slice`, and if it is, I need to do bounds checking on the list. It seems a
bit unpythonic to have to do an isinstance check here, so I am wondering if
I am missing something important about why slices don't raise IndexErrors.

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.



More information about the Python-list mailing list