pythonds
pythonds copied to clipboard
ArrayList code last_index issue - Section 9.2
Chapter 9, Section 2: Python Lists Revisited
The last_index
in this code is tracking one position past the last item in the list.
It starts pointing to index 0 in an empty list.
Then, let's say we add 1 to a fresh instance of ArrayList
, it will be the only (and also the last) item on index 0, but last_index
will be 1
Up to this point, it's not a problem, but could cause problems when trying to pop an item from the list
class ArrayList:
def __init__(self):
self.size_exponent = 0
self.max_size = 0
self.last_index = 0
self.my_array = []
def append(self, val):
if self.last_index > self.max_size - 1: |\label{line:lst_arr_size}|
self.__resize()
self.my_array[self.last_index] = val
self.last_index += 1
But then, there's a problem on this listing:
def insert(self, idx, val):
if self.last_index > self.max_size - 1:
self.__resize()
for i in range(self.last_index, idx - 1, -1): |\label{line:lst_arrlistins_range}|
self.my_array[i + 1] = self.my_array[i]
self.last_index += 1
self.my_array[idx] = val
Let's say we have a list [1,0]
with max_size == 2
. According to the first snippet, after appending one item last_index == 1
. If we insert anything, the first iteration on the loop will try to access the array on index 2, which should cause an IndexError
My suggestions to adjust the issue is as follows:
class ArrayList:
def __init__(self):
self.size_exponent = 0
self.max_size = 0
#last_index initialized with -1
#could also be useful to check for an empty list
self.last_index = -1
self.my_array = []
def append(self, val):
if self.last_index > self.max_size - 1: |\label{line:lst_arr_size}|
self.__resize()
#updating last_index prior to appending the item
self.last_index += 1
self.my_array[self.last_index] = val
def __resize(self):
new_size = 2 ** self.size_exponent
print("new_size = ", new_size)
new_array = [0] * new_size
for i in range(self.max_size): |\label{line:lst_arr_cop1}|
new_array[i] = self.my_array[i]
self.max_size = new_size
self.my_array = new_array
self.size_exponent += 1
def insert(self, idx, val):
#Note the change from > to >=
#this is to assure we will not go out of bounds when accessing
#last_index+1 to shift the list
if self.last_index >= self.max_size - 1:
self.__resize()
for i in range(self.last_index, idx - 1, -1): |\label{line:lst_arrlistins_range}|
self.my_array[i + 1] = self.my_array[i]
self.last_index += 1
self.my_array[idx] = val