Arrays and lists

Index in O(1). Insert in the middle in O(n).

A Python list is a dynamic array: index is Θ(1). Insert or delete in the middle shifts items — Θ(n) in the worst case.

Goal

Count shifts when inserting at index 0 versus appending.

Index is cheap

cities = ["Nairobi", "Mombasa", "Kisumu", "Nakuru"]
print(cities[2])
print("n", len(cities))

One jump to slot 2. That does not walk 0 and 1.

Insert in the middle

def insert_index(xs, i, value):
    steps = 0
    xs = list(xs)
    xs.append(None)
    for j in range(len(xs) - 1, i, -1):
        xs[j] = xs[j - 1]
        steps += 1
    xs[i] = value
    return xs, steps

print(insert_index(["Nairobi", "Kisumu", "Nakuru"], 1, "Mombasa"))
print(insert_index(["Nairobi", "Kisumu", "Nakuru"], 0, "Eldoret"))
print(insert_index(["Nairobi", "Kisumu", "Nakuru"], 3, "Eldoret"))

Insert at 0 shifts every item. Insert at the end shifts none (then one append).

Built-in

xs = ["Nairobi", "Kisumu"]
xs.insert(1, "Mombasa")
print(xs)
xs.append("Nakuru")
print(xs)

list.insert is the real operation. The loop above is the cost model.

Tip

If you need “add at the front” often, a list is the wrong structure. A deque or a linked list fits that ADT better.