Negative indexing in Python is a feature that allows you to access elements from the end of a sequence, such as a list or a string, without knowing its length. Here’s everything you need to know about it:

What is Negative Indexing?

Negative indexing uses negative numbers to access elements starting from the end of the sequence. In this system:

  • -1 refers to the last element,
  • -2 refers to the second last element,
  • and so on.

Usage Examples

Lists
# Define a list
my_list = [10, 20, 30, 40, 50]

# Access elements using negative indexing
print(my_list[-1])  # Output: 50
print(my_list[-2])  # Output: 40
print(my_list[-5])  # Output: 10
Strings
# Define a string
my_string = "Hello, World!"

# Access characters using negative indexing
print(my_string[-1])  # Output: !
print(my_string[-7])  # Output: W
print(my_string[-13]) # Output: H
Tuples
# Define a tuple
my_tuple = (1, 2, 3, 4, 5)

# Access elements using negative indexing
print(my_tuple[-1])  # Output: 5
print(my_tuple[-3])  # Output: 3

Slicing with Negative Indices

Negative indexing can also be used in slicing operations to create sublists or substrings:

# List slicing with negative indexing
my_list = [10, 20, 30, 40, 50]
print(my_list[-3:])   # Output: [30, 40, 50]
print(my_list[-4:-2]) # Output: [20, 30]

# String slicing with negative indexing
my_string = "Hello, World!"
print(my_string[-6:])    # Output: World!
print(my_string[-12:-7]) # Output: ello,

Benefits of Negative Indexing

  1. Convenience: It’s easier to access elements at the end of the sequence without needing to calculate the length.
  2. Readability: Code is often more readable, as you can directly refer to elements like “the last one” or “the second last one”.

Important Considerations

  1. IndexError: Just like with positive indices, using a negative index that’s out of range will raise an IndexError.

    my_list = [10, 20, 30]
    print(my_list[-4])  # IndexError: list index out of range
    
  2. Immutable Sequences: Negative indexing works with both mutable (like lists) and immutable (like strings and tuples) sequences. However, remember that you can’t modify immutable sequences.

  3. Compatibility: Negative indexing is supported in many programming languages with Python being one of the most prominent examples. Other languages may support it with similar syntax or have other ways to achieve the same result.

Practical Use Cases

  • Accessing the last few elements: When dealing with sequences where you need the last few elements, negative indexing is very handy.

    # Last 3 elements of a list
    data = [1, 2, 3, 4, 5, 6, 7]
    last_three = data[-3:]
    print(last_three)  # Output: [5, 6, 7]
    
  • Removing the last element: You can easily remove the last element of a list.

    my_list = [1, 2, 3, 4, 5]
    my_list.pop(-1)
    print(my_list)  # Output: [1, 2, 3, 4]
    
  • Reversing a string: You can reverse a string using slicing with negative indices.

    my_string = "Python"
    reversed_string = my_string[::-1]
    print(reversed_string)  # Output: nohtyP
    

Understanding negative indexing can greatly enhance your ability to work efficiently with sequences in Python, allowing for more concise and readable code.