Problem Formulation
Given a Python iterable such as a list or a string that can be accessed via slicing.
How to use the slicing operation iter[start, stop, step]
so that for given values for start
, stop
, and step
the output is an iterable (slice) containing only the first and the last element of the iterable?
Examples:
'abcd' --> 'ad'
[1, 2, 3, 4, 5] --> [1, 5]
[1, 2] --> [1, 2]
π‘ Note: A great and Pythonic alternative that solves the problem is to be explicit rather than implicit by directly accessing the first and last element with indices 0 and -1, respectively.
[iter[0], iter[-1]]
However, if you explicitly want to know a solution using slicing, read on!
Basic Solution
To get a slice of only the first and last element of an iterable my
(e.g., a list or a string), use the slicing expression my[::len(my)-1]
with default start
and stop
operands and the step
size of len(my)-1
.
my = 'abcd' res = my[::len(my)-1] print(res) # ad
The definition of the step
size is to ignore step-1
elements of the original iterable for every two elements in the slice output.
Thus, if you set step
to len(my)-1
, Python ignores len(my)-1-1 = len(my)-2
elements between two subsequent slice elements.
The first element of the original iterable is part of the resulting slice, then we ignore len(my)-2
elements and include the next element with index len(my)-1
in the slice.
Slicing First and Last List Element
To get a slice of only the first and last element of a list my
, use the slicing expression my[::len(my)-1]
with default start
and stop
operands and the step
size of len(my)-1
.
The following example shows how to apply the same method you’ve already seen to a list:
my = [1, 2, 3, 4, 5] res = my[::len(my)-1] print(res) # [1, 5]
But what if the original input iterable has less than two elements?
Slicing First and Last for an Empty Iterable
The following example shows that only the first element is returned when the iterable is empty—which is what you want!
my = [] res = my[::len(my)-1] print(res) # []
Slicing First and Last for an Iterable with One Element
However, if the iterable has only one element, Python raises an error:
my = [42] res = my[::len(my)-1] print(res)
Output:
Traceback (most recent call last): File "C:\Users\xcent\Desktop\code.py", line 2, in <module> res = my[::len(my)-1] ValueError: slice step cannot be zero
To fix this, you can use the expression max(1,len(my)-1)
as step size of the slicing operation.
This shows how this expression works for iterables with length one as well:
my = [42] res = my[::max(1,len(my)-1)] print(res) # [42]
Learn More
You can learn more about slicing here or watch my tutorial video: