Home/Learn/Python A–Z/Lists — Python's Workhorse

Lists — Python's Workhorse

Beginner
Data Structures

Lists are mutable, ordered, dynamic arrays — the data structure behind 80% of Python code, with slicing, in-place methods, and O(1) append but O(n) insert-at-front.

Overview

A Python list is a dynamic array of object references (like Java's ArrayList, not LinkedList). It grows automatically, holds mixed types, and supports the richest operation set in the language: slicing, concatenation, in-place mutation. Knowing which operations are O(1) vs O(n) — append is amortized O(1), insert(0, x) is O(n), x in list is O(n) — is exactly what interviewers listen for when you narrate a DSA solution.

Core Operations & Slicing

Slicing returns a NEW list: lst[start:stop:step]. Negative indexes count from the end. lst[:] is the idiomatic shallow copy; lst[::-1] reverses.

Operations with their complexity
nums = [10, 20, 30, 40, 50]

nums.append(60)          # add at end            O(1)
nums.insert(0, 5)        # add at front          O(n) — shifts all!
nums.remove(30)          # delete by VALUE       O(n)
last = nums.pop()        # remove & return last  O(1)
first = nums.pop(0)      # remove first          O(n)

print(nums[1:3])         # slice [start:stop)
print(nums[-2:])         # last two
print(nums[::-1])        # reversed copy
copy = nums[:]           # shallow copy

nums.sort()                        # in-place, returns None!
sorted_copy = sorted(nums, reverse=True)  # new list

# Trap: result = nums.sort() -> result is None
matrix = [[0] * 3 for _ in range(3)]   # correct 3x3
bad = [[0] * 3] * 3                    # 3 references to SAME row!

Lists as Stacks (and why not Queues)

append/pop from the END make a perfect O(1) stack. Never use pop(0) for a queue — it shifts every element (O(n)); use collections.deque instead.

Stack with a list; queue with deque
# Stack — valid parentheses (classic interview problem)
def is_valid(s):
    stack = []
    pairs = {")": "(", "]": "[", "}": "{"}
    for ch in s:
        if ch in "([{":
            stack.append(ch)
        elif not stack or stack.pop() != pairs[ch]:
            return False
    return not stack

print(is_valid("({[]})"))   # True
print(is_valid("(]"))       # False

# Queue — use deque, NOT list.pop(0)
from collections import deque
q = deque([1, 2, 3])
q.append(4)          # enqueue O(1)
print(q.popleft())   # dequeue O(1) — list.pop(0) would be O(n)

Key Points to Remember

  • 1append/pop at the end: O(1); insert/pop at the front: O(n) — use deque for queues
  • 2sort() mutates and returns None; sorted() returns a new list
  • 3Slices copy: lst[:] shallow-copies, lst[::-1] reverses
  • 4[[0]*3]*3 shares one row object — use a comprehension for 2D grids

Interview Questions

Sign in to ask Aria
1

What is the time complexity of list.append vs list.insert(0, x)? Why?

EasyAmazon
2

Why is [[0]*n]*m a bug for building a matrix? What is the fix?

MediumFlipkart
3

Difference between sort() and sorted()?

EasyTCS

Ask Aria about Lists — Python's Workhorse

Your personal AI tutor — ask anything about this concept

Revision Status

Personal Notes

Sign in to save personal notes for this topic.

Discussion

Sign in to join the discussion.

Loading discussion…