Python’s New Slice Functions

” Well, when the Python community asked for more slice functions… they got ’em. And boy oh boy, are we ever grateful!

Introducing: `slice(start=None, stop=None, step=None)` and its new friends `reversed()`, `itertools.islice()`, and `itertools.count()`. These slice functions have been added to Python’s standard library in version 3.10 (currently in beta), and they are here to make our lives easier… or at least more interesting!

To kick things off, the new `slice(start=None, stop=None, step=None)` function. This slice function is a generalization of the existing `[start:stop:step]` syntax that we all know and love (or hate). The main difference here is that you can now pass keyword arguments for each parameter instead of having to write them out in order.

For example, let’s say you want to slice a list from index 2 up to but not including index 7 with a step size of 3:

# Define a list of numbers
my_list = [1, 2, 3, 4, 5, 6, 7]

# Use the slice function to extract a portion of the list
# The start parameter specifies the starting index of the slice
# The stop parameter specifies the ending index of the slice (not included)
# The step parameter specifies the step size between each element in the slice
# In this case, we want to start at index 2, end at index 7 (not included), and have a step size of 3
# This will return a new list with the elements [3, 6]
my_list_slice = my_list[2:7:3]

# Print the result
print(my_list_slice) # Output: [3, 6]

Pretty cool, right? But wait there’s more! The new `reversed()` function is a generator that produces the reverse of an iterable. This can be used in combination with slicing to create some pretty interesting effects:

# The following script uses the `reversed()` function to print the reverse of a sliced list.

# First, we define a list of numbers.
my_list = [1, 2, 3, 4, 5]

# Next, we use the `slice()` function to create a slice object that will return the elements from index 1 to 4 (excluding index 4).
# Note: The `slice()` function returns a slice object, which can be used to slice a sequence (such as a list or string).
my_slice = slice(1, 4) # returns [2, 3, 4]

# Then, we use the `reversed()` function to create a generator that will produce the reverse of the slice object.
# Note: The `reversed()` function returns a reverse iterator, which can be used to iterate over a sequence in reverse order.
my_reversed_slice = reversed(my_slice) # returns [4, 3, 2]

# Finally, we use a for loop to iterate over the reversed slice and print each element.
for item in my_reversed_slice:
    print(item) # prints 4, 3, 2

And if that’s not enough for you, the `itertools.islice()` function allows you to create a slice object without actually slicing anything! This can be useful in situations where you want to iterate over an iterator multiple times with different slice parameters:

# Import the itertools module
import itertools

# Create a list of numbers
my_list = [1, 2, 3, 4, 5]

# Iterate over a slice of the list using the islice() function
# The islice() function takes in three parameters: the iterable object, start index, and end index
# It returns an iterator object that contains the elements within the specified slice range
# In this case, the first iteration will print out [2, 3, 4] since the start index is 1 and the end index is 4
for item in itertools.islice(my_list, 1, 4):
    print(item)

# Iterate over the entire list using the islice() function
# The second iteration will print out [1, 2, 3, 4, 5] since the start index is 0 and the end index is None
# Passing in None as the end index will return all elements from the start index to the end of the list
for item in itertools.islice(my_list, 0, None):
    print(item)

Finally, the `itertools.count()` function allows you to create an iterator that generates a sequence of numbers starting from zero (or any other number) with a given step size:

# The `itertools.count()` function allows you to create an iterator that generates a sequence of numbers starting from zero (or any other number) with a given step size.

# The `for` loop iterates through the sequence of numbers generated by the `count()` function, starting from 10 and incrementing by 1 each time. The `item` variable stores the current number in the sequence.

for item in count(start=10): # returns [10, 11, 12, ...]
    
    # The `if` statement checks if the current number in the sequence is greater than 50. If it is, the loop is terminated using the `break` keyword.
    if item > 50: break
    
# The `print()` function outputs the first 10 numbers in the sequence generated by the `count()` function. The `islice()` function is used to limit the number of items in the sequence to 10.

print(list(islice(count(), 10))) # returns [10, 11, 12, 13, 14, 15]

They may not be the most exciting addition to the language (that honor goes to `asyncio`), but they are definitely useful and worth checking out.

SICORPS