Reputation: 113
I have been looking at this too long. I am writing code to use known algorithms to increase the size of an ArrayList as I am adding to it. Every time the size of the ArrayList changes I add the new size to an array which is then added to a dictionary.
Here is the code for the ArrayList class I am using
class ArrayList:
def __init__(self, growfn):
'''Initializes the empty ArrayList with the specified growth function.'''
self.size = 0
self.used = 0
self.array = []
self.grow = growfn
def get(self, index):
if index < self.size:
return self.array[index]
# exception handling
return None
def add(self, value):
if self.used == self.size:
newSize = self.grow(self.size)
if newSize <= self.size:
# exception handling
return
newArray = self.array[:]+[None for i in range(self.size,newSize)]
self.array = newArray
self.size = newSize
self.array[self.used] = value
self.used = self.used + 1
return None
Here is the code I have written to test this. This function takes 3 parameters: A list containing the max sizes of the array, the function for the algorithm I am using to increase the size of the ArrayList, and the number of tries that it will run for.
def analyzePerformance(nList, gfn, tries):
data = []
sizes_array = []
averages = []
arr = ArrayList(gfn)
for num in nList:
for j in range(tries):
current_size = 0
start = time()
while arr.size < num:
arr.add(None)
if arr.size != current_size:
sizes_array.append(arr.size)
current_size = arr.size
end = time()
averages.append(end - start)
data.append(dict({'grow': gfn, 'N': num, 'seconds': mean(averages), 'sizes': sizes_array}))
return data
And finally the code where I call to the function
def main():
for result in analyzePerformance([1,10,100], double, 11):
print(result)
double is a function that simply doubles the size of the array
Here is my current output:
{'grow': <function double at 0x7f3274eb4f28>, 'N': 1, 'seconds': 3.034418279474432e-07, 'sizes': [1, 2, 4, 8, 16, 32, 64, 128]}
{'grow': <function double at 0x7f3274eb4f28>, 'N': 10, 'seconds': 4.659999500621449e-07, 'sizes': [1, 2, 4, 8, 16, 32, 64, 128]}
{'grow': <function double at 0x7f3274eb4f28>, 'N': 100, 'seconds': 7.369301535866477e-07, 'sizes': [1, 2, 4, 8, 16, 32, 64, 128]}
And here is what I need the output to be
{'grow': <function double at 0x7f3274eb4f28>, 'N': 1, 'seconds': 3.034418279474432e-07, 'sizes': [1]}
{'grow': <function double at 0x7f3274eb4f28>, 'N': 10, 'seconds': 4.659999500621449e-07, 'sizes': [1, 2, 4, 8, 16]}
{'grow': <function double at 0x7f3274eb4f28>, 'N': 100, 'seconds': 7.369301535866477e-07, 'sizes': [1, 2, 4, 8, 16, 32, 64, 128]}
Why is it that when I add new elements to the dictionary with different lengths of sizes arrays it updates the old dictionaries to have the longer arrays as well? Any help is appreciated, thanks!
Upvotes: 1
Views: 61
Reputation: 31584
You may want to have a look for Shallow and deep copy operations:
Assignment statements in Python do not copy objects, they create bindings between a target and an object. For collections that are mutable or contain mutable items, a copy is sometimes needed so one can change one copy without changing the other.
For your next code, the sizes_array
will be reused among different iterations, although it has been added into data list
:
data.append(dict({'grow': gfn, 'N': num, 'seconds': mean(averages), 'sizes': sizes_array}))
To fix this, you need to change above to next:
data.append(dict({'grow': gfn, 'N': num, 'seconds': mean(averages), 'sizes': sizes_array.copy()}))
With above, you will see a copied object for sizes_array
which meet your requirement.
Upvotes: 1