Python Arrays

Arrays in Python are data structures that store multiple values of the same type in a single variable. While Python has several array-like structures, the most commonly used are:



Basic List Example :

fruits = ["apple", "banana", "cherry"]


Basic Array Operations

Creating Arrays :

# Using square brackets
numbers = [1, 2, 3, 4, 5]
# Using list() constructor
empty_list = list()
another_list = list((1, 2, 3))  # Note the double parentheses
# Using array module
import array
int_array = array.array('i', [1, 2, 3])  # 'i' for signed integers


Accessing Elements :

fruits = ["apple", "banana", "cherry"]
print(fruits[0])  # Accessing the first element
print(fruits[1])  # Accessing the second element
print(fruits[-1]) # Accessing the last element


Modifying Arrays :

# Changing elements
my_array[1] = 25  # [10, 25, 30, 40, 50]
# Adding elements
my_array.append(60)  # [10, 25, 30, 40, 50, 60]
my_array.insert(2, 15)  # [10, 25, 15, 30, 40, 50, 60]
# Removing elements
my_array.remove(25)  # [10, 15, 30, 40, 50, 60]
popped = my_array.pop()  # 60, array is now [10, 15, 30, 40, 50]


Intermediate Array Concepts

Array Slicing :

nums = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# Basic slice
print(nums[2:5])  # [2, 3, 4]
# With step
print(nums[1:8:2])  # [1, 3, 5, 7]
# Negative indices
print(nums[-5:-2])  # [5, 6, 7]
# Omitting indices
print(nums[:3])  # [0, 1, 2]
print(nums[4:])  # [4, 5, 6, 7, 8, 9]
print(nums[::2])  # [0, 2, 4, 6, 8]


Array Methods :

# Sorting
numbers = [3, 1, 4, 1, 5, 9, 2]
numbers.sort()  # [1, 1, 2, 3, 4, 5, 9]
numbers.sort(reverse=True)  # [9, 5, 4, 3, 2, 1, 1]
# Reversing
numbers.reverse()  # [1, 1, 2, 3, 4, 5, 9]
# Searching
index = numbers.index(4)  # 3
count = numbers.count(1)  # 2
# Copying
copy = numbers.copy()  # Shallow copy


List Comprehensions :

# Basic comprehension
squares = [x**2 for x in range(10)]
# With condition
even_squares = [x**2 for x in range(10) if x % 2 == 0]
# Nested comprehension
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flattened = [num for row in matrix for num in row]


Advanced Array Concepts

Multidimensional Arrays :

# 2D array (list of lists)
matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]
# Accessing elements
print(matrix[1][2])  # 6
# Using NumPy for better performance
import numpy as np
np_matrix = np.array(matrix)
print(np_matrix[:, 1])  # Column at index 1: [2, 5, 8]


Array Performance Optimization :

# Time complexity of common operations
"""
Operation       | Time Complexity
----------------+----------------
Index access    | O(1)
Append          | O(1)
Pop last        | O(1)
Pop intermediate| O(n)
Insert          | O(n)
Delete          | O(n)
Search          | O(n)
"""

# Using deque for faster appends/pops from both ends
from collections import deque
d = deque([1, 2, 3])
d.appendleft(0)  # Faster than list.insert(0, 0)
d.popleft()      # Faster than list.pop(0)


Memory Efficient Arrays :

# Using array module for homogeneous data
import array
int_arr = array.array('i', [1, 2, 3])  # More memory efficient than list
float_arr = array.array('d', [1.0, 2.0, 3.0])
# Typecodes:
# 'b' - signed char, 'B' - unsigned char
# 'i' - signed int, 'I' - unsigned int
# 'f' - float, 'd' - double


NumPy Arrays for Scientific Computing :

import numpy as np
# Creating NumPy arrays
arr = np.array([1, 2, 3])          # 1D array
matrix = np.array([[1, 2], [3, 4]]) # 2D array
# Array operations
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
print(a + b)  # [5 7 9]
print(a * 2)  # [2 4 6]
# Universal functions
print(np.sqrt(a))  # [1.         1.41421356 1.73205081]


Unique Array Techniques

Circular Buffer Implementation :

class CircularBuffer:
    def __init__(self, size):
        self.buffer = [None] * size
        self.size = size
        self.index = 0
        
    def add(self, item):
        self.buffer[self.index % self.size] = item
        self.index += 1
        
    def __getitem__(self, idx):
        return self.buffer[idx % self.size]

    def __repr__(self):
        return str(self.buffer)
# Usage
cb = CircularBuffer(3)
cb.add(1); cb.add(2); cb.add(3); cb.add(4)
print(cb)  # [4, 2, 3] - oldest element (1) was overwritten


Array-Based Queue :

class ArrayQueue:
    def __init__(self):
        self.items = []
    
    def enqueue(self, item):
        self.items.insert(0, item)
    
    def dequeue(self):
        return self.items.pop()
    
    def size(self):
        return len(self.items)
    
    def is_empty(self):
        return self.items == []


Memoryview for Efficient Array Manipulation :

# Using memoryview for efficient byte manipulation
data = bytearray(b'abcdef')
view = memoryview(data)
view[2:4] = b'XY'
print(data)  # bytearray(b'abXYef')


Array-Based Binary Heap :

class MinHeap:
    def __init__(self):
        self.heap = []
    
    def parent(self, i):
        return (i-1)//2
    
    def insert(self, key):
        self.heap.append(key)
        i = len(self.heap) - 1
        while i != 0 and self.heap[self.parent(i)] > self.heap[i]:
            self.heap[self.parent(i)], self.heap[i] = self.heap[i], self.heap[self.parent(i)]
            i = self.parent(i)
    
    def extract_min(self):
        if not self.heap:
            return None
        if len(self.heap) == 1:
            return self.heap.pop()
        
        root = self.heap[0]
        self.heap[0] = self.heap.pop()
        self.heapify(0)
        return root
    
    def heapify(self, i):
        smallest = i
        left = 2*i + 1
        right = 2*i + 2
        
        if left < len(self.heap) and self.heap[left] < self.heap[smallest]:
            smallest = left
        if right < len(self.heap) and self.heap[right] < self.heap[smallest]:
            smallest = right
        if smallest != i:
            self.heap[i], self.heap[smallest] = self.heap[smallest], self.heap[i]
            self.heapify(smallest)


Performance Comparison :

import timeit
import numpy as np
from array import array

# List vs array module vs NumPy performance
size = 1_000_000

# Sum operation
list_time = timeit.timeit('sum(lst)', setup=f'lst = list(range({size}))', number=100)
array_time = timeit.timeit('sum(arr)', setup=f'arr = array.array("i", range({size}))', number=100)
numpy_time = timeit.timeit('np.sum(np_arr)', setup=f'import numpy as np; np_arr = np.arange({size})', number=100)

print(f"List sum: {list_time:.4f} sec")
print(f"Array sum: {array_time:.4f} sec")
print(f"NumPy sum: {numpy_time:.4f} sec")


Python Array (List) Methods Summary Table


Method Description Example Output
append(x) Adds item x to the end of the list fruits.append("orange") ['apple', 'banana', 'cherry', 'orange']
insert(i, x) Inserts item x at position i fruits.insert(1, "grape") ['apple', 'grape', 'banana', 'cherry']
remove(x) Removes first occurrence of x fruits.remove("banana") ['apple', 'cherry']
pop([i]) Removes and returns item at index i (last if not given) fruits.pop() 'cherry'
sort() Sorts the list in ascending order numbers.sort() [1, 2, 3, 4, 5]
reverse() Reverses the list numbers.reverse() [5, 4, 3, 2, 1]
index(x) Returns index of first occurrence of x fruits.index("apple") 0
count(x) Returns number of times x appears fruits.count("apple") 1
copy() Returns a shallow copy of the list fruits.copy() ['apple', 'banana', 'cherry']
extend(iterable) Adds all items from iterable to the end fruits.extend(["kiwi", "melon"]) ['apple', 'banana', 'cherry', 'kiwi', 'melon']
clear() Removes all items from the list fruits.clear() []