Python Slice Get First and Last Element

Rate this post

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: