Python Essentials for AI Engineer

Course Content

Python Essentials for AI Engineer

6 sections · 48 lessons

What are some commonly used list methods?


A list is one continuous block of slotsp0p1p2p3p4p5012345insert(0) orpop(0): shift allappend or pop(): O(1)100,000 calls to pop(0) move about 5 billion items; deque.popleft is constant time.
Where you add or remove matters more than which method you call — the front of a list costs O(n).

What you need to know

The methods, with what they return

Python
nums = [3, 1, 2]nums.append(4)        # [3, 1, 2, 4]nums.extend([5, 6])   # [3, 1, 2, 4, 5, 6]nums.insert(0, 9)     # [9, 3, 1, 2, 4, 5, 6]nums.remove(1)        # [9, 3, 2, 4, 5, 6]   first matching VALUEprint(nums.pop())     # 6  -> removes and returns the last itemprint(nums.pop(0))    # 9  -> or the item at an indexprint(nums)           # [3, 2, 4, 5]print(nums.index(2), nums.count(2))   # 1 1result = nums.sort()print(result, nums)   # None [2, 3, 4, 5]  -> sorted in place, returns Nonenums.reverse()print(nums)           # [5, 4, 3, 2]
MethodChanges the list?ReturnsCost
append(x)yesNoneO(1)
extend(it)yesNoneO(k) for k new items
insert(i, x)yesNoneO(n)
remove(x)yesNone (ValueError if missing)O(n)
pop() / pop(i)yesthe itemO(1) at end, O(n) elsewhere
index(x), count(x)nointO(n)
sort(), reverse()yesNoneO(n log n), O(n)
copy()nonew listO(n)

Why the front of a list is slow

A Python list is a dynamic array: items sit in one continuous block of memory. Adding at the end just fills the next slot (Python keeps spare room, so this is O(1) on average). Inserting or removing at position 0 means shifting every other item by one slot — O(n). If you need a queue that takes items from the front, use collections.deque, which is O(1) at both ends.

sort() vs sorted()

list.sort() sorts the existing list and returns None. sorted(iterable) works on any iterable and returns a new list, leaving the original untouched. Both accept key= and reverse=True, and both are stable: items with equal keys keep their original order.

A real-life example

A batch job sends 100,000 queued prompts to an LLM, taking one at a time from the front of a list:

Python
from collections import dequeprompts = [f"Summarise ticket {i}" for i in range(100_000)]queue = deque(prompts)          # O(1) popleftsent = 0while queue:    prompt = queue.popleft()    # with a list, prompts.pop(0) is O(n) each time    sent += 1print(sent)                     # 100000

With prompts.pop(0), each call shifts up to 99,999 items, so the whole loop does about 5 billion item moves and takes far longer than the network calls it feeds. deque.popleft() does it in constant time. The same job had a second bug: ranked = results.sort(key=...) left ranked as None, which crashed the report step. The fix was ranked = sorted(results, key=...).

Follow-up questions to expect

  • "What is the difference between remove, pop and del?" — remove(x) deletes by value; pop(i) deletes by index and returns the item; del lst[i] deletes by index or slice and returns nothing.
  • "Why is pop(0) slow?" — Every remaining item shifts one slot left, so it is O(n). Use deque.popleft().
  • "Is copy() a deep copy?" — No, it is shallow: nested lists inside are shared. Use copy.deepcopy for nested data.