Reputation: 89
I've seen plenty of Python list slice questions here, I don't believe I'm duplicating anything despite it touching on many of those same questions. My question relates to shortening a list using slices, to create a new list and to update the original list.
My task would be to define a Class
method which accepts two arguments (word_list, num)
and manipulate word_list
using slicing. I keep slicing until word_list
is empty, storing each slice in a new list. It's not important which end I slice from in terms of the contents of the slice but simply that I can keep slicing and maintain an accurate record of events.
Take the following:
word_list = ["once", "upon", "a", "time", "there", "lived", "an", "old", "man"]
sub_list1 = word_list[:2] # ["once", "upon"]
word_list = word_list[2:] # ["a", "time", "there", "lived", "an", "old", "man"]
compare this with
word_list = ["once", "upon", "a", "time", "there", "lived", "an", "old", "man"]
sub_list2 = word_list[-2:] # ["old", "man"]
word_list = word_list[:-2] # ["once", "upon", "a", "time", "there", "lived"]
In the first example above the list elements get "shunted down" as the slices are taken, as opposed to the second wherein the list simply gets shorter and nothing "moves". Am I inventing a problem or are there any actual implications in slicing word_list
differently?
Upvotes: 1
Views: 233
Reputation: 17322
not sure if I understand your issue, but I can't see any actual implications between your first and second example, it is just your interpretation
you can have a look over the performance whitch is the same:
import numpy as np
import struct
import sys
from simple_benchmark import BenchmarkBuilder
b = BenchmarkBuilder()
@b.add_function()
def positive_slicing(my_list):
sub_list = my_list[:2]
my_list = my_list[2:]
@b.add_function()
def negative_slicing(my_list):
sub_list = my_list[-2:]
my_list = my_list[:-2]
@b.add_arguments('slicing list')
def argument_provider():
for exp in range(2, 7):
size = 10**exp
yield size, ['some random example'] * size
r = b.run()
r.plot()
Upvotes: 1
Reputation: 531045
Extended slice syntax works by creating a slice
object to pass to the appropriate __getitem__
method. foo[x:y:z]
becomes foo.__getitem__(slice(x, y, z))
.
No assumptions are made about missing values; the value None
is simply passed along to slice
. So your expressions become
word_list[:2] -> word_list.__getitem__(slice(None, 2, None))
word_list[2:] -> word_list.__getitem__(slice(2, None, None))
word_list[:-2] -> word_list.__getitem__(slice(None, -2, None))
word_list[-2:] -> word_list.__getitem__(slice(-2, None, None))
It is up to the implementation of __getitem__
to decide how to treat each None
value. Typically, context is taken into account. If the step is positive, a missing start is treated as 0; if it's negative, as -1
. A missing step usually defaults to 1, regardless of the start and stop positions; that's why something like foo[10:0]
is empty rather than assuming you want to use a step of -1.
Upvotes: 2