WRITELOOP

DATA STRUCTURES - ARRAYS

Arrays are one of the most fundamental data structures to be used on algorithms. Here are some notes regarding arrays and its' python implementation (lists)

2022 September 5
  • arrays: in-memory contiguous elements

  • lists are Python’s implementation of arrays

  • my_array.sort(): take care, it will be applied inplace, changing myarray (lists are mutable, remember? ;)

  • sorted(my_array): does not change my_array

  • my_array.append(): add to the array as the last element - quicker than insert. Python optimizes that, but since it reserves a number of indexes, if the array grows too much, it will need some time to backstage move the current elements to a new memory position with more space to hold more items.

  • my_array.insert(0, 555): add on specific index of the array (555 on index 0) - this can slow down you algorithm when the array grows in size, since it will move all other elements

  • my_array.remove(555): this removes a element by its value, NOT the index - that is analogous to insert, it will have to shift all remaining elements.

  • my_array[1] = None: a better way to “remove” an element from the array, since that will not have to shift all remaining elements.

  • del my_array(1): remove the element that is on index 1

  • min(my_array): minimum number on the array

  • max(my_array): maximum number on the array

  • You can use binary search in python using the bisect function that is on the stdlib:
import bisect
index_that_has_555_on_an_array = bisect.bisect(my_array, 555)
  • Almost all python algorithms for search are O(n log n). python’s bisect does that on O(log n) - the fastest ;)

  • Insert an element on the binary tree:

import bisect
bisect.insort(my_array, 666)
  • my_array = list(range(100)): generates a list with sorted numbers, from 0 to 99

  • Python’s array implementation with lists has some “gotchas” when you copy lists. Keep them in mind:

A = [1, 2, 3]
B = A   # this is a SHALLOW COPY - it just creates a "pointer" - changes on A reflect on B and vice-versa
B[0] = 999 # 999
A[0]  # 999 (danger!!!)
a = [1,2,3]
b = list(a)  # creates a DEEP COPY of the values - changes on A do NOT reflect on B and vice-versa
b[0] = 999

a[0]  # 1, as expected
a = [{'test': 123, 'bbb': 456}]
b = list(a)
b[0]['test'] = 999  # both A and B dicts inside the list will be changed (danger!!!)

# to copy the values on a dict (to fix the problem on the previous statement), you must use python's "copy' lib:
import copy
a = [{'test': 123, 'bbb': 456}]
b = copy.deepcopy(a)
b[0]['test'] = 999  # Only the b list will be changed
a[0]['test']  # The a list will be 123, as expected
  • Say you want to change positions from the 2nd and 3rd element on the list below. To avoid using temporary variables and do that on the most efficient pythonic way, you can directly shift both the array’s positions:
a = [1, 2, 3, 4]
a[2], a[1] = a[1], a[2]

(that is possible because lists are mutable)