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??
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])
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.
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.
Python slicing can be done in two ways:Using a slice() method. Using array slicing [ : : ] method.
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
orj
in the slice expression are replaced by zero orsys.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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With