List slicing is a technique in which a range of items of a
list can be accessed. The new list is a subset of the original list.
If x is a list,
then x[p:q]
returns the portion of x
starting with index p and
up to index q
but not including q.
For slicing, we use the format:
variable[start:stop:step]
Remember that all the three fields are optional.
The shortest slice notation in python is x[:],
which is also exactly equivalent to the notation x[::].
Consider the list
x = [1, "python", 101, 7.8, -9, "java", 13].
Here, len(x), i.e., number of items is 7.
This len(x) value will be handy in slicing.
Applying a slice [3:6] on this list, we will get an output of [7.8, -9, 'java']
We are coming to the details of how this works.
Take the slice notation x[::].
Here, we get none of the values of start, stop and step.
Now, having a slice notation in our hand, first we have to check the
third field step. The value of step decides the
workflow of the whole slice.
The notations [:], [::], [p:], [p:q], [:q], [p::], [p:q:], [:q:]
have a common thing in them; the step value is absent.
Note: If step is None, or it is blank, or empty, its value defaults to 1.
So, the above mentioned slice notations translate to
[::1], [::1], [p::1], [p:q:1], [:q:1], [p::1], [p:q:1], [:q:1].
A step value of zero is invalid.
If step is positive, start value will be 0. This refers to the first item of the list;
stop value will be the length of the list.
If step is negative, start value will be -1. This refers to the last item of the list;
stop value will be -(length+1).
At this point, we have a slice notation in our hand where all the
start, stop and step values are defined with values, for example: [p:q:r]
Take a list z = [11, 22, 33, 44, 55, 66, 77].
For a slice notation [2:5:1],
the interpreter starts with the item
at index 2 and stops at the item before index 5.
So output of z[2:5:1] is [33, 44, 55]
Note that item at index 5 is not included.
So stop value somehow translates to stop before.
For a slice notation [5:2:-1],
the interpreter starts with the item
at index 5 and stops at the item before index 2
in reverse direction because of negative step value -1.
So output of z[5:2:-1] is [66, 55, 44].
In the following, item at index 4 is not included, i.e., the item at stop index is not inclusive.
Note: The item at stop index will not be included in the output list.
When start index is omitted and step is positive, slicing starts from the beginning of the list. In this case start defaults to zero.
For any list, x[:4] is the same as x[0:4]
When stop index is omitted and step is positive, slicing starts from start index upto the end of the list. Default for stop, in this case, is the length of the list len(x).
x[4:] is the same as x[4:len(x)].
If x is a list or tuple,
len(x) returns the number of items in it.
If x is a string,
len(x) returns the number of characters in it.
Note: Indexing returns an item, while slicing returns a list.
When both start and stop are omitted, the entire list is the output.
In this way, we can copy a list by slicing. Both the lists will have the exact same items, though their identities will be different. Also x[:] and x[::] are the same.
Note: The slice notation [:] and [::] can copy a tuple as done in case of lists.
For this list, x[-6:-4] and x[1:3] are the same.
While x[::] returns the entire list, x[::2] returns the alternate items beginning from index 0 upto the end of the list
x[::2] forces the interpreter to include the first item, discard the 2nd, include the 3rd, discard the 4rth... upto the end of list.
x[::3] forces the interpreter to include the first item, discard the 2nd and 3rd, include the 4rth, discard the 5th and 6th... upto the end of list.
x[1:6:2] translates to "start with item at index 1, include alternate items, stop before index 6",
A negative step value enables the slicing from the end to the beginning of a list.
Slice x[::-1] reverses the entire list.
A step of -2 in x[::-2] reverses the list with the alternate values.
Consider the slice x[-2::-4].
Here, start index is -2 (6th. item),
stop index is - len(x) - 1 = -8
(because of negative step),
step -4 forces every 4rth alternate items to include.
Note: Though there is no index -8, in slicing this works because
counting stops before -8. In indexing, x[-8]
will raise an IndexError.
If the start or stop indices are out of range, python will raise no error, and return an empty list silently. We must be careful about this behaviour of python while slicing.
Note that executing print(x[7]) will raise an IndexError, because there is no index 7.
In the previous page, we modified lists by indexing.
In the above, we targeted the second item and modified it.
Since slicing returns a portion of the list, we can modify a part of the list
by slice assignment.
The slice num[1:4] targets the
[20, 30, 40] part of the original list.
This part is replaced by the assigned list
[22, 33, 44].
Note: Since slicing returns a list, slice assignment requires a list.
Take another example. The slice z[0:2] targets the first two items ["php", "vb"].
So they are replaced by the assigned items ["python", "c++"].
A list can be extended in the following way.
What is happening here? If we display the value of
a[2:2], we get an empty list [].
We assign a list ["ram", "rom"] to a[2:2].
Python inserts this new list at index 2 of list a.
In this way, list a is extended. Note that no item is overwritten.
In the following, the list is extended by overwriting one item.
If we display the value of
a[2:3], we get [3].
So, in statement
a[2:3] = ["ram", "rom"]
the target list [3]
is replaced by the assigned list ["ram", "rom"].
So, item at index 2 is overwritten.
The following code shrinks a list by slice assignment.
a[0:2] targets the [1, 2] part. It is replaced by the assigned empty list []. Thus the list is shrinked.
That we know the basics of slicing, it will be easy
for us to use the slice() function.
Python slice() also
accepts three parameters, start, stop and step. The stop parameter
is mandatory, other two are optional.
The function returns a slice object of 'slice' type.
When we pass one argument for slice(),
python takes it as the stop value, inserts a
None(which is actually 0)
as start value, and another None
as step value (which is actually 1).
Now, as our first_three slice is ready,
we can apply it to any list.
Note: The slice() function returns a slice object.
Let us create a slice that always returns the last two items of any list.
When we pass two arguments for slice(), python
takes first one as the start value,
second one as the stop value, and
inserts None(which is actually 1) as step value.
Obviously, to specifically mention start value,
we have to include both start and stop values.
To specifically mention step value,
we have to include all start, stop and step values.
The slice() function is somehow similar to the
python range(), which also accepts three parameters
start, stop and step, the stop
being mandatory, other two are optional.
# Summary
--- x ---
Want to leave a message for me?