Arrays/Python/DynamicArray
From charlesreid1
The DynamicArray class in Python demonstrates the use of a low-level ctype array to keep track of objects.
Features:
- Implements an array-based structure that works like a Python list, has many of the same features and O() operational costs
- Handles negative indices like mylist[-1]
- "Dynamic shrinkage" that works like a Python list - as more elements are removed, the array is automatically resized to be smaller
- See pop() method implementation
The class
""" Goodrich et al Data Structures in Python Chapter 5: Array-Based Sequences Question R-5.4 Expand on the DynamicArray class to support negative indexing with the __getitem__ method. Question C-5.16 Implement a pop() method for DynamicArray. It should remove the last item in the array. It should shrink the capacity in half if the number of elements drops below N/4. """ import ctypes class DynamicArray: """ A dynamic array class that works like a list. """ def __init__(self): self._n = 0 # number of elements self._capacity = 1 # default array capacity self._A = self._make_array(self._capacity) # low-level guts def __getitem__(self,k): if(0<=k<self._n): return self._A[k] elif(-self._n<=k<0): return self._A[self._n+k] else: raise IndexError("Invalid index: Requested index {0} exceeds number of elements {1}".format(k,self._n)) def append(self,obj): """Add obj to end of array""" if(self._n==self._capacity): # We are out of space, so resize. # Resize will update capacity for us. self._resize(2*self._capacity) self._A[self._n] = obj self._n += 1 def pop(self): """Pop obj from end of array""" self._A[self._n] = None self._n -= 1 if(self._capacity//4 > self._n): self._resize(self._capacity//2) def _resize(self,c): """ Resize to capacity c (private)""" print("Resizing array: {0:4d} elements, {1:5d} capacity".format(self._n,c)) B = self._make_array(c) # bigger array for k in range(self._n): B[k] = self._A[k] # copy existing elements only self._A = B # forget the old array self._capacity = c # update capacity def _make_array(self,n): """Make the internal array (private)""" return (n*ctypes.py_object)() if __name__=="__main__": import random, sys a = DynamicArray() print("Appending 1,000 elements to array...") for j in range(1000): a.append(random.randint(0,9)) print("Done.\n") print("Accessing array at individual positive/negative indices...") for ix in [0, 10, 35, -10, -999, 999, -1000]: print("Index {0:4d}\tDynamicArray value: {1:2d}".format(ix,a[ix])) print("Done.\n") print("Accessing array at invalid index...") try: ix = 1000 print("Index {0:4d}\tDynamicArray value: {1:2d}".format(ix,a[ix])) except IndexError: print("Correctly throws IndexError for index {0}.".format(ix)) print("Done.\n") print("Popping 995 elements from array...") for j in range(995): a.pop() print("Done.\n")
Expected output
$ python DynamicArray.py Appending 1,000 elements to array... Resizing array: 1 elements, 2 capacity Resizing array: 2 elements, 4 capacity Resizing array: 4 elements, 8 capacity Resizing array: 8 elements, 16 capacity Resizing array: 16 elements, 32 capacity Resizing array: 32 elements, 64 capacity Resizing array: 64 elements, 128 capacity Resizing array: 128 elements, 256 capacity Resizing array: 256 elements, 512 capacity Resizing array: 512 elements, 1024 capacity Done. Accessing array at individual positive/negative indices... Index 0 DynamicArray value: 5 Index 10 DynamicArray value: 9 Index 35 DynamicArray value: 4 Index -10 DynamicArray value: 2 Index -999 DynamicArray value: 1 Index 999 DynamicArray value: 7 Index -1000 DynamicArray value: 5 Done. Accessing array at invalid index... Correctly throws IndexError for index 1000. Done. Popping 995 elements from array... Resizing array: 255 elements, 512 capacity Resizing array: 127 elements, 256 capacity Resizing array: 63 elements, 128 capacity Resizing array: 31 elements, 64 capacity Resizing array: 15 elements, 32 capacity Resizing array: 7 elements, 16 capacity Done.
Arrays Part of Computer Science Notes
Series on Data Structures Python: Arrays/Python · Arrays/Python/Sizeof · Arrays/Python/AppendCost · Arrays/Python/CaesarCipher · Arrays/Python/CompactArrays · Arrays/Python/DynamicArray Java: Arrays/Java · Arrays/Java/CaesarCipher · Arrays/Java/FisherYates · Arrays/Java/PythonList · Arrays/Java/Repeatedly_Remove Categories: Category:Python Arrays
|