[Python-ideas] Add a datatype collections.ListView

Steven D'Aprano steve at pearwood.info
Fri Apr 18 03:35:35 CEST 2014


On Thu, Apr 17, 2014 at 01:28:19PM -0500, Ryan Hiebert wrote:
> On Thu, Apr 17, 2014 at 1:12 PM, Terry Reedy <tjreedy at udel.edu> wrote:
> 
> > Range gives you a lot for free, including slicing.
> >
> 
> I have wondered why Python has both slice and range, given the power that
> range has. Is there anything that slice can do that range can't, or are
> there some functional differences?

Because one is screwdriver and the other is a spanner? (Just don't ask 
me which one is which :-)

But seriously, while they have similar signatures, they are semantically 
very different. range objects are concrete interators that produce 
numeric values, and all three arguments must be integers:

py> range(2, 3, None)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'NoneType' object cannot be interpreted as an integer


while slices are an extremely generic, type-agnostic mechanism for 
pointing to multiple indexes of some sequence:

py> slice("spam", 2.5, 17)
slice('spam', 2.5, 17)


Slices have no meaning of their own, it's up to the sliced object to 
interpret them. The above slice will raise TypeError when used on a 
list, but may be accepted happily by some other custom sequence type.

As far as built-in objects go, slices with negative indexes, or with 
end=None, can't be interpreted as indexes until you know which sequence 
they are applied to:

range(1, 6, 2) always yields 1, 3, 5.
slice(1, 6, 2) always refers to indexes 1, 3, 5.

but

range(1, -6, 2) is always empty.
slice(1, -6, 2) may be empty, or it could refer to index 1 alone, 
    or to indexes 1, 3, or indexes 1, 3, 5, or 1, 3, 5, 7, or ... 

In general, you cannot tell what indexes the slice will cover until 
you know what sequence it has been applied to. Built-in lists and tuples 
allow slices to extend past the ends of the sequence. That concept is 
meaningless with range.

So despite the fact that slice() and range() have similar signatures, 
they are used differently, and have very different semantics.



-- 
Steven


More information about the Python-ideas mailing list