Anyone following my twitter feed can tell you that I am a great fan of the Python programming language. It is an incredible programming language and it is filled with many neat language features that truly help programmer productivity and code readability. For a quick tutorial, visit the informal Python tutorial here. If you would like to suggest a feature to cover, please don’t hesitate to let me know. Leave a comment and let’s have a discussion!
Introduction
The first feature in Python that I would like to cover is slicing and sliding. Although, slicing is a very well-known feature of the Python programming language; the companion “sliding” or “stepping” feature is not particularly documented in places where it should be (like here) and I rarely see any usage of it in regular Python code. Slicing and sliding together make for some sweet list manipulation action! Slicing and sliding is the equivalent to Batman and Robin, one is feared and loved while the sidekick occasionally pops up here and there to complement Batman hehe. I have seen usage of term stepping (perhaps more frequently) and sliding, use the term you prefer. They are perfectly interchangeable. In my opinion though, slicing and sliding sounds so much better together (hehe one letter change and the letters are consecutive ZOMG!) and since the features are tied together why not make the names sound similar. I am going to stick with slicing and sliding until someone convinces me not to.
Definition
Slicing is the ability to create a list (in the abstract data type sense) from another list by cutting pieces of that other list.
Off course, you can do this by looping through the list and picking the elements you want to put in your new list but slicing is great because it provides a cleaner and more readable syntax to do just that. The syntax looks like this:
l[start:end] # slices from start to end - 1
l[start:] # slices from start through the rest of the list
l[:end] # slices from the beginning to end - 1
l[:] # slices through the entire list i.e. does a copy of the list
Example 1
>>> l = range(5) # produces this list: [0,1,2,3,4]
>>> print l
[0, 1, 2, 3, 4]
>>> l[2:4]
[2, 3]
>>> l[2:]
[2, 3, 4]
>>> l[:4]
[0, 1, 2, 3]
>>> l[:]
[0, 1, 2, 3, 4]
So what is sliding or stepping? Sliding allows you to specify an increment between the elements to cut from your list. If you wanted to slice every 2 elements, instead of specifying an increment of 1, you specify 2.
The syntax looks like this:
# slices from start to end - 1 but slide by the step value
l[start:end:step]
# slices through the entire list i.e. does a copy of the list
l[::]
Example 2
>>> l = range(10)
>>> print l
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> l[::2]
[0, 2, 4, 6, 8]
>>> l[::3]
[0, 3, 6, 9]
>>> l[::-1] # ZOMG
[9, 8, 7, 6, 5, 4, 3, 2, 1]
>>> l[::-2] # BUT WATCH OUT!
[9, 7, 5, 3, 1]
Why it is awesome?
So why is this awesome? Well as you can see from above, you can select every two elements of the list, reverse a list, reverse a slice of the list… well you can basically do a lot of things that would have required you to create a loop to retrieve specific slices of a list. Your code for grabbing elements from a list is significantly shorter and more concise. Add in the sliding (or stepping) notation and you suddenly have a very powerful method of manipulating lists.
Slice Objects
Now that slicing and sliding has been explained, the underlying implementation of the above syntax is done by calling the slice method with the same parameters.
slice([start,] stop[, step])
However, this method will return a slice object. This object conveniently holds a start, stop and step read-only variables that you can access. You can pass around slice objects easily and reuse the variables. (Clean code yay!) You apply a slice object by doing the following:
>>> # The following is equivalent to list[1::2]
>>> s = slice(1, None, 2) # None is the default for empty.
>>> l = range(5)
>>> print l
[0, 1, 2, 3, 4]
>>> l[s] # Apply the slice!
[1, 3]
Bonus: Interview Question for Python Candidates:
Reverse a list in one line and explain how it works? It works through the use of a stepping parameter. We slice the whole but we specify that we want to step in the negative direction by 1, i.e. slide backwards from the end of the list by 1 step.
print mylist[::-1]