Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python - Basic vs extended slicing

When experimenting with slicing I noticed a strange behavior in Python 2.7:

class A:
    def __getitem__(self, i):
        print repr(i)
a=A()
a[:] #Prints slice(0, 9223372036854775807, None)
a[::] #prints slice(None, None, None)
a[:,:] #prints (slice(None, None, None), slice(None, None, None))

When using a single colon in the brackets, the slice object has 0 as start and a huge integer as end. However, when I use more than a single colon, start and stop are None if not specified.

Is this behaviour guaranteed or implementation specific?

The Documentation says that the second and third case are extended slicing, while the first case is not. However, I couldn't find any clear explanation of the difference between basic and extended slicing.

Are there any other "special cases" which I should be aware of when I override __getitem__ and want to accept extended slicing??

like image 699
Bernhard Avatar asked Aug 19 '16 11:08

Bernhard


People also ask

What is extended slicing in Python?

The slice syntax is a handy way to refer to sub-parts of sequences – typically strings and lists. The slice s[start:end] is the elements beginning at start and extending up to but not including end. E.g letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g'] print(letters[2:5])

What is the difference between slicing and range in Python?

In Python, range objects are not iterators but are iterables. So slicing a range() function does not return an iterator but returns an iterable instead.

Is Python slicing inclusive or exclusive?

Python is a zero-indexed language (things start counting from zero), and is also left inclusive, right exclusive you are when specifying a range of values. This applies to objects like lists and Series , where the first element has a position (index) of 0.

What are different ways of slicing a string in Python?

Python slicing can be done in two ways:Using a slice() method. Using array slicing [ : : ] method.


1 Answers

For Python 2 [:] still calls __getslice__(self, i, j) (deprecated) and this is documented to return a slice slice(0, sys.maxsize, None) when called with default parameters:

Note that missing i or j in the slice expression are replaced by zero or sys.maxsize, ...

(emphasis mine). New style classes don't implement __getslice__() by default, so

If no __getslice__() is found, a slice object is created instead, and passed to __getitem__() instead.

Python 3 doesn't support __getslice__(), anymore, instead it constructs a slice() object for all of the above slice expressions. And slice() has None as default:

Note: Slicing is done exclusively with the following three methods. A call like

a[1:2] = b

is translated to

a[slice(1, 2, None)] = b

and so forth. Missing slice items are always filled in with None.

like image 144
dhke Avatar answered Oct 19 '22 05:10

dhke