Complexity Cheat Sheet for Python Operations

Python built-in data structures like list, sets, dictionaries provide a large number of operations making it easier to write concise code but not being aware of their complexity can result in unexpected slow behavior of your python code.
Prerequisite: List, Dictionaries, Sets
For example:
A simple dictionary lookup Operation can be done by either :
if key in d:
or
if dict.get(key)
The first has a time complexity of O(N) for Python2, O(1) for Python3 and the latter has O(1) which can create a lot of differences in nested statements.
Important points:
- Lists are similar to arrays with bidirectional adding and deleting capability.
- Dictionaries and Set use Hash Tables for insertion/deletion and lookup operations.
This Cheat sheet can be referred for choosing operations that are efficient with respect to time.
List Operations
| Operation | Examples | Complexity class | |
|---|---|---|---|
| Average case | Amortised Worst case | ||
| Append | l.append(item) | O(1) | O(1) |
| Clear | l.clear() | O(1) | O(1) |
| Containment | item in/not in l | O(N) | O(N) |
| Copy | l.copy() | O(N) | O(N) |
| Delete | del l[i] | O(N) | O(N) |
| Extend | l.extend(…) | O(N) | O(N) |
| Equality | l1==l2, l1!=l2 | O(N) | O(N) |
| Index | l[i] | O(1) | O(1) |
| Iteration | for item in l: | O(N) | O(N) |
| Length | len(l) | O(1) | O(1) |
| Multiply | k*l | O(k*N) | O(k*N) |
| Min, Max | min(l), max(l) | O(N) | O(N) |
| Pop from end | l.pop(-1) | O(1) | O(1) |
| Pop intermediate | l.pop(item) | O(N) | O(N) |
| Remove | l.remove(…) | O(N) | O(N) |
| Reverse | l.reverse() | O(N) | O(N) |
| Slice | l[x:y] | O(y-x) | O(y-x) |
| Sort | l.sort() | O(N*log(N)) | O(N*log(N)) |
| Store | l[i]=item | O(1) | O(1) |
For more information, refer to Internal working of list in Python.
Note: Tuples have the same operations (non-mutable) and complexities.
Dictionary Operations
| Operation | Examples | Complexity class | |
|---|---|---|---|
| Average case | Amortised Worst case | ||
| Clear | d.clear() | O(1) | O(1) |
| Construction | dict(…) | O(len(d)) | O(len(d)) |
| Delete | del d[k] | O(1) | O(N) |
| Get | d.get() | O(1) | O(N) |
| Iteration(key, value, item) | for item in d: | O(N) | O(N) |
| Length | len(d) | O(1) | O(1) |
| Pop | d.pop(item) | O(1) | O(N) |
| Pop Item | d.popitem() | O(1) | O(1) |
| Returning Views | d.values() | O(1) | O(1) |
| Returning keys | d.keys() | O(1) | O(1) |
| Fromkeys | d.fromkeys(seq) | O(len(seq)) | O(len(seq)) |
Note: Defaultdict has operations same as dict with same time complexity as it inherits from dict.
Set Operations
| Operation | Examples | Complexity class | |
|---|---|---|---|
| Average case | Amortised Worst case | ||
| Add | s.add(item) | O(1) | O(N) |
| Clear | s.clear() | O(1) | O(1) |
| Copy | s.copy() | O(N) | O(N) |
| Containment | item in/not in s | O(1) | O(N) |
| Creation | set(…) | O(len(s)) | O(len(s)) |
| Discard | s.discard(item) | O(1) | O(N) |
| Difference | s1-s2 | O(len(s1)) | O(len(s1)) |
| Difference Update | s1.difference_update(s2) | O(len(s2)) | – |
| Equality | s1==s2, s1!=s2 | O(min(len(s1), len(s2))) | O(min(len(s1), len(s2))) |
| Intersection | s1 & s2 | O(min(len(s1), len(s2))) | O(min(len(s1), len(s2))) |
| Iteration | for item in s: | O(N) | O(N) |
| Is Subset | s1<=s2 | O(len(s1)) | O(len(s1)) |
| Is Superset | s1>=s2 | O(len(s2)) | O(len(s1)) |
| Pop | s.pop() | O(1) | O(N) |
| Union | s1|s2 | O(len(s1)+len(s2)) | – |
| Symmetric Difference | s1^s2 | len(s1) | O(len(s1)*len(s2)) |
For more information, refer to Internal working of Set in Python
Note: Frozen sets have the same operations (non-mutable) and complexities.



