I want to know what's the use of built-in
function slice
and how can I use it,
the direct way of pythonic slicing I know l1[start:stop:step]
, I want to know if I have object of slice
then howto?
views:
65answers:
5There is good deal of discussion on slicing at SO
Are you looking for something specific?
The slice
function returns slice objects. Slice objects are one of Python's internal types, which are optimized for read performance - all of their attributes are read-only.
Altering slice
could be useful if wish to change the default behaviour. For example, lxml
uses slice notation to access DOM elements (however, I haven't confirmed how they did that myself).
You create a slice by calling slice with the same fields you would use if doing [start:end:step] notation:
sl = slice(0,4)
To use the slice, just pass it as if it were the index into a list or string:
>>> s = "ABCDEFGHIJKL"
>>> sl = slice(0,4)
>>> print s[sl]
'ABCD'
Let's say you have a file of fixed-length text fields. You could define a list of slices to easily extract the values from each "record" in this file.
data = """\
0010GEORGE JETSON 12345 SPACESHIP ST HOUSTON TX
0020WILE E COYOTE 312 ACME BLVD TUCSON AZ
0030FRED FLINTSTONE 246 GRANITE LANE BEDROCK CA
0040JONNY QUEST 31416 SCIENCE AVE PALO ALTO CA""".splitlines()
fieldslices = [slice(*fielddef) for fielddef in [
(0,4), (4, 21), (21,42), (42,56), (56,58),
]]
fields = "id name address city state".split()
for rec in data:
for field,sl in zip(fields, fieldslices):
print field, ':', rec[sl]
print
Prints:
id : 0010
name : GEORGE JETSON
address : 12345 SPACESHIP ST
city : HOUSTON
state : TX
id : 0020
name : WILE E COYOTE
address : 312 ACME BLVD
city : TUCSON
state : AZ
id : 0030
name : FRED FLINTSTONE
address : 246 GRANITE LANE
city : BEDROCK
state : CA
id : 0040
name : JONNY QUEST
address : 31416 SCIENCE AVE
city : PALO ALTO
state : CA
Square brackets following a sequence denote either indexing or slicing depending on what's inside the brackets:
>>> "Python rocks"[1] # index
'y'
>>> "Python rocks"[1:10:2] # slice
'yhnrc'
Both of these cases are handled by the __getitem__()
method of the sequence (or __setitem__()
if on the left of an equals sign.) The index or slice is passed to the methods as a single argument, and the way Python does this is by converting the slice notation, (1:10:2
, in this case) to a slice object: slice(1,10,2)
.
So if you are defining your own sequence-like class or overriding the __getitem__
or __setitem__
or __delitem__
methods of another class, you need to test the index argument to determine if it is an int
or a slice
, and process accordingly:
def __getitem__(self, index):
if isinstance(index, int):
... # process index as an integer
elif isinstance(index, slice):
start, stop, step = index.indices(len(self)) # index is a slice
... # process slice
else:
raise TypeError("index must be int or slice")
A slice
object has three attributes: start
, stop
and step
, and one method: indices
, which takes a single argument, the length of the object, and returns a 3-tuple: (start, stop, step)
.
>>> class sl:
... def __getitem__(self, key): print key
...
>>> s = sl()
>>> s[1:3:5]
slice(1, 3, 5)
>>>